Печать имени и значения макроса

У меня есть программа C с множеством оптимизаций, которые можно включить или отключить с помощью #define s. Когда я запускаю свою программу, я хотел бы знать, какие macros были определены во время компиляции.

Поэтому я пытаюсь написать макрофункцию для печати фактического значения макроса. Что-то вроде этого:

 SHOW_DEFINE(X){\ if( IS_DEFINED(X) )\ printf("%s is defined and as the value %d\n", #X, (int)X);\ else\ printf("%s is not defined\n", #X);\ } 

Однако я не знаю, как заставить его работать, и я подозреваю, что это невозможно, кто-нибудь имеет представление о том, как это сделать?

(Обратите внимание, что это необходимо компилировать, даже если макрос не определен!)

Написание MACRO, которое расширяется до другого MACRO, потребует, чтобы препроцессор работал дважды на нем.
Это не сделано.

Вы можете написать простой файл,

 // File check-defines.c int printCompileTimeDefines() { #ifdef DEF1 printf ("defined : DEF1\n"); #else // DEF1 printf ("undefined: DEF1\n"); #endif // DEF1 // and so on... } 

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

Если у вас есть #DEFINE строки внутри исходного файла, а не Makefile ,
Переместите их в другой файл Header и включите этот заголовок во все исходные файлы,
включая этот check-defines.c .

Надеюсь, у вас есть одинаковый набор определений, разрешенных во всех ваших исходных файлах.
В противном случае было бы разумно пересмотреть страtagsю ваших определений.


Чтобы автоматизировать генерацию этой функции ,
вы можете использовать макрос M4 (или даже скрипт AWK ).
M4 становится вашим предварительным процессором.

Пока вы готовы смириться с тем фактом, что SOMESTRING = SOMESTRING указывает, что SOMESTRING не определен (просмотрите его, поскольку токен не был переопределен!?!), Тогда необходимо выполнить следующее:

 #include  #define STR(x) #x #define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x)) #define CHARLIE -6 #define FRED 1 #define HARRY FRED #define NORBERT ON_HOLIDAY #define WALLY int main() { SHOW_DEFINE(BERT); SHOW_DEFINE(CHARLIE); SHOW_DEFINE(FRED); SHOW_DEFINE(HARRY); SHOW_DEFINE(NORBERT); SHOW_DEFINE(WALLY); return 0; } 

Выход:

 BERT=BERT CHARLIE=-6 FRED=1 HARRY=1 NORBERT=ON_HOLIDAY WALLY= 
 #ifdef MYMACRO printf("MYMACRO defined: %d\r\n", MYMACRO); #endif 

Я не думаю, что то, что вы пытаетесь сделать, возможно. Вы запрашиваете информацию во время выполнения, которая была обработана перед компиляцией. Строка «MYMACRO» ничего не значит после того, как CPP расширила ее до своей ценности внутри вашей программы.

Вы не указали используемый вами компилятор. Если это gcc, gcc -E может помочь вам, поскольку он останавливается после этапа предварительной обработки и печатает результат предварительной обработки. Если вы сравниваете результат gcc -E с исходным файлом, вы можете получить часть того, что хотите.

Почему бы просто не протестировать его с помощью препроцессора?

  #if defined(X) printf("%s is defined and as the value %d\n", #X, (int)X); #else printf("%s is not defined\n", #X); #endif 

Можно также вставить это в другой тест, чтобы не печатать его каждый раз:

  #if define(SHOW_DEFINE) #if defined(X) printf("%s is defined and as the value %d\n", #X, (int)X); #else printf("%s is not defined\n", #X); #endif #endif 

Волновая библиотека от boost может быть полезна и для того, чтобы делать то, что вы хотите. Если ваш проект достаточно велик, я думаю, что стоит попробовать. Это препроцессор C ++, но они одинаковы 🙂

Я считаю, что то, что вы пытаетесь сделать, невозможно. Если вы можете изменить способ работы #define , я предлагаю что-то вроде этого:

 #define ON 1 #define OFF 2 #define OPTIMIZE_FOO ON #define OPTIMIZE_BAR OFF #define SHOW_DEFINE(val)\ if(val == ON) printf(#val" is ON\n");\ else printf(#val" is OFF\n"); 

Вполне возможно, что проблема заключается в «неопределенной» части. Если вы использовали макрокоманды для активации / деактивации частей своего кода, вы могли бы просто сделать:

 #define SHOW_DEFINE(X) \ do { \ if (X > 0) \ printf("%s %d\n", #X, (int)X); \ else \ printf("%s not defined\n", #X); \ } while(0) 

Основываясь на Кришаррисе, ответьте, я сделал это. Хотя мой ответ не очень приятный, это то, чего я хотел.

 #define STR(x) #x #define SHOW_DEFINE(x) printf("%s %s\n", #x, strcmp(STR(x),#x)!=0?"is defined":"is NOT defined") 

Только ошибка, которую я нашел, – это определение не должно #define XXX XXX (с XXX равно XXX).

Этот вопрос очень близок от макроса, который печатает выражение и оценивает его (с помощью __STRING) . Ответ Кришарриса очень близок к ответу на предыдущий вопрос.

вы можете использовать целочисленную переменную, инициализированную 1. умножить #define на эту переменную и напечатать значение переменной.