C: Препроцессор в макросах?

#c #macros #c-preprocessor

#c #макросы #c-препроцессор

Вопрос:

Есть ли способ использовать ключевые слова препроцессора внутри макроса? Если есть какой-то escape-символ или что-то в этом роде, я об этом не знаю.

Например, я хочу создать макрос, который расширяется до этого:

 #ifdef DEBUG
    printf("FOO%s","BAR");
#else
    log("FOO%s","BAR");
#endif
  

из этого:

 PRINT("FOO%s","BAR");
  

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

Ответ №1:

Вы не можете сделать это напрямую, нет, но вы можете определить PRINT макрос по-разному в зависимости от того, определен ли DEBUG :

 #ifdef DEBUG
    #define PRINT(...) printf(__VA_ARGS__)
#else 
    #define PRINT(...) log(__VA_ARGS__)
#endif
  

Комментарии:

1. Ага. Я знал, что это должно было быть возможно каким-то образом, но я просто смотрел не с того конца. Спасибо.

2. @Джеймс Макнеллис: Это создаст ошибку, PRINT("FOO%s","BAR"); которая будет расширена до log("FOO%s","BAR");; , например.

3. @equality: в C89 / 90 нет переменных макросов, нет.

4. @nightcracker — Хотя это и некрасиво, это ни в коем случае не ошибка.

5. @nightcracker: Я уже заметил это и удалил постороннее ; .

Ответ №2:

Просто сделай это наоборот:

 #ifdef DEBUG
    #define PRINT printf
#else
    #define PRINT log
#endif
  

Ответ №3:

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

 #ifdef DEBUG
# define DEBUG_PRINT printf
#else
# define DEBUG_PRINT log
#endif
  

Если у вас есть переменные макросы, вы могли бы сделать #define DEBUG_PRINTF(...) func(__VA_ARGS__) вместо этого. Работает в любом случае. Второй позволяет вам использовать указатели на функции, но я не могу представить, зачем вам это нужно для этой цели.