Есть ли способ сделать #define внутри другого #define?

Я знаю, что я пытаюсь стрелять в ногу;) Однако это позволит мне сделать остаток (большую сумму) кода более компактным и читаемым.

Есть ли какой-нибудь сложный способ создать макрос препроцессора внутри другого макроса препроцессора?

Вот пример, что я ищу. Мой реальный сценарий более сложный

// That's 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 } 

Стандарт C ++ говорит (16.3.4.3):

Полученная полностью макрозаменяемая последовательность токенов предварительной обработки [… расширения макроса …] не обрабатывается как директива предварительной обработки, даже если она похожа на одну …

Так нет, нет «официального» способа достижения того, что вы хотите с помощью макросов.

Нет. Даже если макрос расширяется во что-то, что выглядит как предпроцессорная директива, расширение не оценивается как директива предварительной обработки.

В дополнение к ответам выше, если вы действительно хотели предварительно обработать исходный файл дважды, что почти наверняка не то, что вы на самом деле хотите сделать, вы всегда можете вызвать свой компилятор следующим образом:

 g++ -E input.cpp | g++ -c -x c++ - -o output.o 

То есть, запустите файл через препроцессор, затем запустите предварительно обработанный вывод через канал через полную процедуру компиляции, включая второй шаг предварительной обработки. Для того, чтобы это имело достаточно хорошие шансы на работу, я бы предположил, что вам нужно быть достаточно осторожным в том, как вы определили и использовали свои macros, и все это, скорее всего, не стоило бы того, время.

Если вы действительно хотите использовать macros, используйте стандартные макро-решения. Если вам действительно нужно метапрограммирование времени компиляции, используйте шаблоны.

Что касается немного примечания, это напоминает мне о том, что raytracing language POV-Ray сильно использовал довольно сложный язык предварительной обработки с директивами управления streamом, такими как #while которые допускали условное повторение, вычисления времени компиляции и другие подобные лакомства. Это было бы так на C ++, но это просто не так, поэтому мы просто делаем это по-другому.

Нет. Препроцессор является однопроходным. Он не переоценивает расширения макросов.

Что бы вы купили, во всяком случае? Вы можете выполнить то же самое, что и ваш пример, просто «вложив» второй макрос в первый. например:

 #define MACRO(B) B+B void foo() { int a = MACRO(5); } 

Как уже отмечалось, можно # включить конкретный файл более одного раза с активными различными определениями макросов. Это может сделать его практичным для достижения некоторых эффектов, которые не могут быть практически достигнуты с помощью каких-либо других средств.

В качестве простого примера, во многих встроенных системах указатель-указатель очень дорог по сравнению с прямым доступом к переменной. Код, который использует много указателей, может быть в два раза больше и медленнее, чем код, который просто использует переменные. Следовательно, если конкретная подпрограмма используется с двумя наборами переменных, в сценарии, в котором обычно можно было бы передать указатель на структуру, а затем использовать оператор стрелки, может быть намного эффективнее простого поставить подпрограмму в свой собственный файл (Обычно я использую расширение .i), которое # включается один раз без макроса _PASS2, и во второй раз. Этот файл может затем #ifdef _PASS2 / # else определять macros для всех переменных, которые должны быть разными в течение двух проходов. Даже при том, что код генерируется дважды, на некоторых микронах, которые занимают меньше места, чем при использовании оператора стрелки с переданными указателями.

Взгляните на m4. Он похож на cpp, но рекурсивный и гораздо более мощный. Я использовал m4 для создания структурированного языка для ассемблеров, например

  cmp r0, #0 if(eq) mov r1, #0 else add r1, #1 end 

«If», «else» и «end» – это вызовы макросов m4, которые я написал, которые генерируют прыжки и метки, а остальная – assembly. Чтобы вложить эти конструкторы if / else / end, вам нужно определить внутри макроса.

  • #define в Java
  • Существуют ли какие-либо macros, чтобы определить, скомпилирован ли мой код для Windows?
  • #define vs const в Objective-C
  • Stringification - как это работает?
  • Каковы допустимые символы для имен макросов?
  • Как сделать строку char из значения макроса C?
  • «#Include» текстовый файл в программе на языке C как символ
  • C ++ #include семантика
  • Почему кто-то использует #define для определения констант?
  • Как использовать #if внутри #define в препроцессоре C?
  • Должен ли я использовать #define, enum или const?
  • Interesting Posts

    Где найти ключ продукта Win 10 после обновления?

    Производятся ли конструкторы перемещения автоматически?

    Мерцание экрана на HP dv6t-7000

    Перегрузка метода для нулевого аргумента

    Неявное преобразование типа C ++ с шаблоном

    Как вернуть список пользователей, если я использую простое имя пользователя и пароль для Firebase

    Объединение: not () селекторов в CSS

    создавая «радарную диаграмму» (также называемую сюжетной звездой, участок паука) с использованием ggplot2 в R

    Реляционная алгебра для банковского сценария

    Понимание контекстов в Spring MVC

    Горизонтальные линии внезапно вспыхивают на дисплее ноутбука

    Установить тип документа HTML5 с помощью XSLT

    Рекурсивный вызов ConcurrentHashMap.computeIfAbsent () никогда не завершается. Ошибка или «функция»?

    Сколько стоит стоимость гигабайта данных на жестком диске?

    Если / else в ANTLR с использованием прослушивателей

    Давайте будем гением компьютера.