Есть ли способ сделать #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, вам нужно определить внутри макроса.

  • Представление больших чисел в исходном коде для удобочитаемости?
  • Как проверить ОС с помощью директивы препроцессора?
  • C ++ concat два строковых литерала `const char`
  • Псевдо-дженерики в C
  • MSVC не расширяет __VA_ARGS__ правильно
  • Массив размера массива, который отклоняет указатели
  • Расширение макроскопического расширения MSVC ++
  • Когда macros C ++ полезны?
  • Использование X-Macros в реальном мире
  • Как я могу увидеть исходный файл C / C ++ после предварительной обработки в Visual Studio?
  • Являются ли typedef и #define одинаковыми в c?
  • Interesting Posts

    Как установить традиционные параметры принтера из приложения современного пользовательского интерфейса (Reader)?

    Использование SimpleMembership с первой моделью EF

    Должен ли я использовать одно или двойное обозначение двоеточия для псевдоэлементов?

    Двойной USB-накопитель

    Как я могу получить доступ к опции «Открыть команду здесь здесь» в Windows без переноса?

    Каковы различия между -std = c ++ 11 и -std = gnu ++ 11?

    Разница между make и build в Android Studio

    Возможно ли напечатать тип переменной в стандартном C ++?

    Как получить экземпляр classа типа, связанного с привязкой к контексту?

    Сохранять точность с двойным в Java

    Подсчет ожидающего сектора на жестком диске

    Можно ли считать ветви с неопределенным поведением недостижимыми и оптимизированными как мертвый код?

    Что такое Sysprep? Как это полезно?

    Как отправить местоположение устройства на сервер при необходимости

    Как узнать, сколько дискового пространства осталось с помощью Java?

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