Есть ли способ сделать #define внутри другого #define?
Я знаю, что я пытаюсь застрелить себя в ноге;) Однако это позволит мне сделать остаток (большую сумму) кода более компактным и читаемым.
Есть ли какой-нибудь сложный способ создать макрос препроцессора внутри другого макроса препроцессора?
Вот пример, что я ищу. Мой реальный сценарий более сложный
// That what I want to do and surely C++ doesn't like it.
#define MACROCREATER(B) #define MACRO##B B+B
void foo()
{
MACROCREATOR(5) // This should create new macro (#define MACRO5 5+5)
int a = MACRO5; // this will use new macro
}
Ответы
Ответ 1
В стандарте С++ говорится (16.3.4.3):
Полученный результат полностью маркеры с предварительной заменой макросов последовательность [... расширения макроса...] не обрабатывается как препроцессора, даже если это напоминает один...
Нет, нет "официального" способа достижения того, что вы хотите с помощью макросов.
Ответ 2
Нет. Даже если макрос расширяется во что-то, что выглядит как предпроцессорная директива, расширение не оценивается как директива предварительной обработки.
Ответ 3
В качестве дополнения к вышеприведенным ответам, если вы действительно хотели предварительно обработать исходный файл дважды и mdash, что почти наверняка не то, что вы действительно хотите сделать, вы всегда можете вызвать свой компилятор следующим образом:
g++ -E input.cpp | g++ -c -x c++ - -o output.o
То есть, запустите файл через препроцессор, затем запустите предварительно обработанный вывод через канал через полную процедуру компиляции, включая второй шаг предварительной обработки. Для того, чтобы это имело достаточно хорошие шансы на работу, я бы предположил, что вам нужно быть достаточно осторожным в том, как вы определили и использовали свои макросы, и все это, скорее всего, не стоило бы того, время.
Если вы действительно хотите использовать макросы, используйте стандартные макро-решения. Если вы действительно хотите метапрограммирование времени компиляции, используйте шаблоны.
В слегка связанной заметке это напоминает мне о том, что raytracing language POV-Ray сильно использовал довольно сложный язык предварительной обработки с директивами управления потоком, такими как #while
, которые допускали условное повторение, вычисления времени компиляции, и другие подобные лакомства. Если бы это было так на С++, но это просто не так, поэтому мы просто делаем это по-другому.
Ответ 4
Нет. Препроцессор однопроходный. Это не переоценивает расширения макроса.
Ответ 5
Как уже отмечалось, можно # включить конкретный файл более одного раза с активными различными определениями макросов. Это может сделать его практичным для достижения некоторых эффектов, которые не могут быть практически достигнуты с помощью каких-либо других средств.
В качестве простого примера, во многих вложенных системах указатель-указатель очень дорог по сравнению с прямым доступом к переменной. Код, который использует много указателей, может быть в два раза больше и медленнее, чем код, который просто использует переменные. Следовательно, если конкретная подпрограмма используется с двумя наборами переменных, в сценарии, в котором обычно можно было бы передать указатель на структуру, а затем использовать оператор стрелки, может быть намного эффективнее простого поставить подпрограмму в свой собственный файл (Обычно я использую расширение .i), которое # включается один раз без макроса _PASS2, и во второй раз. Этот файл может затем #ifdef _PASS2/# else определять макросы для всех переменных, которые должны быть разными в течение двух проходов. Несмотря на то, что код генерируется дважды, на некоторых микронах, которые занимают меньше места, чем с помощью оператора стрелки с переданными указателями.
Ответ 6
Взгляните на m4. Он похож на cpp, но рекурсивный и гораздо более мощный. Я использовал m4 для создания структурированного языка для ассемблеров, например.
cmp r0, #0
if(eq)
mov r1, #0
else
add r1, #1
end
"if", "else" и "end" - это вызовы макросов m4, которые я написал, которые генерируют прыжки и метки, а остальная - сборка. Чтобы вложить эти конструкторы if/else/end, вам нужно определить внутри макроса.