как использовать #ifdef внутри макроса? '#' не сопровождается параметром макроса - PullRequest
1 голос
/ 08 ноября 2019

Я беру проект, который написан на c, и есть много макросов.

Я хочу использовать новый макрос, чтобы проверить, активирован макрос или нет.

Носимвол # зарезервирован в макросе. Как исправить мой код? Спасибо:)

#define CHECK_MACRO( macro )\
#ifdef macro
printf("defined "#macro"\n");\
#else
printf("not defined "#macro"\n");\
#endif

Ответы [ 2 ]

0 голосов
/ 08 ноября 2019

Дополнительное примечание - препроцессор m4 - история / наследие.

В первые дни Unix для генерации кода использовался процессор 'm4'. Он имеет расширенные возможности cpp (или может быть cpp - уменьшенная версия m4). Специально, он имеет лучшую поддержку многострочных макросов. Он по-прежнему используется в различных пакетах.

Стоит отметить, что добавление генерации кода в ваш код сделает его более сложным для обслуживания / отладки.

Например: a.m4

define(`CHECK_MACRO', `
#ifdef $1
printf ("defined #$1\n") ;
#else
printf ("undef #$1\n") ;
#endif
')

#include <stdio.h>

void main(void)
{
  CHECK_MACRO(FOO) ;
  CHECK_MACRO(BAR) ;
}

Затем сборка / запуск

m4 a.m4 > a.c
cc a.c
./a.out
  undef #FOO
  undef #BAR

cc a.c -DFOO
./a.out
  defined #FOO
  undef #BAR

Обычно генерация была интегрирована в Makefile с правилом %.c: %.m4: m4 -s $< > $@ -s помогает отследить номер строки исходного кода (она скомпилирует совпадение номера строки ошибкиисходный файл a.m4.

0 голосов
/ 08 ноября 2019

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...