#ifdef inside #define - PullRequest
       1

#ifdef inside #define

63 голосов
/ 07 апреля 2011

Я пытаюсь написать что-то вроде этого:

#define COV_ON(x) \
                #ifdef COVERAGE_TOOL \
                    _Pragma (COVERAGE #x)
                #endif

Есть ли способ определить COV_ON как это? Я знаю, что то, что я сделал выше, неправильно, так как я не могу иметь #ifdef внутри #define. (# недопустимый символ в #define). Так есть ли решение?

Ответы [ 6 ]

74 голосов
/ 07 апреля 2011

Не возможно. Сделайте это наоборот:

#ifdef COVERAGE_TOOL
#define COV_ON(x) _Pragma (COVERAGE #x)
#else
#define COV_ON(x)
#endif
21 голосов
/ 07 апреля 2011

Просто переверните его:

#ifdef COVERAGE_TOOL
#define COV_ON(x) _Pragma (COVERAGE #x)
#else
#define COV_ON(x) /* foo */
#endif
6 голосов
/ 07 апреля 2011

Вы не можете. Но вы можете поменять местами #ifdef и #define:

#ifdef COVERAGE_TOOL
#   define COV_ON(x) _Pragma (COVERAGE #x)
#else
#   define COV_ON(x)
#endif
6 голосов
/ 07 апреля 2011
#ifdef COVERAGE_TOOL
    #define COV_ON(x) _Pragma (COVERAGE #x)
#else
    #define COV_ON(x)
#endif
5 голосов
/ 17 апреля 2017

Это старый вопрос, но он нуждался в обновленном ответе.

Вместо использования встроенного ifdef внутри макроса, вы можете выборочно определить макрос __VA_ARGS__, чтобы сделать то же самое

#ifdef COVERAGE_TOOL
#define IF_COVERAGE_TOOL(...) __VA_ARGS__
#else
#define IF_COVERAGE_TOOL(...)
#endif
#define COV_ON(x) IF_COVERAGE_TOOL( _Pragma (COVERAGE #x) )

Это похоже на ifdef, за исключением того, что вы получаете круглые скобки, чтобы разграничить начало и конец (у большинства IDE нет проблем со сложением кода), хотя вы все еще можете использовать #define и #ifdef в контексте#include не допускается.Чтобы получить встроенные возможности, подобные #else, вы можете определить соответствующий макрос следующим образом:

//#define FOO
#ifdef FOO
#define IF_FOO(...) __VA_ARGS__ 
#define NO_FOO(...)
#else
#define IF_FOO(...)
#define NO_FOO(...) __VA_ARGS__
#endif

IF_FOO(
  #define BAR 5
  int foo = BAR;
)
NO_FOO(
  #define foo 5
)

Только один из NO_FOO()/IF_FOO будет генерировать код.

OK, этохак, но можем ли мы сделать это БОЛЬШЕ полезным, чем #ifdefs ... Возможно, логическая логика и конфигурация?Позволяет настроить некоторые таблицы истинности (и пару вспомогательных макросов).

#define PASTE_(x,y) x##y
#define PASTE(x,y) PASTE_(x,y)
#define PASTE3_(x,y,z) x##y##z
#define PASTE3(x,y,z) PASTE3_(x,y,z)
#define Y(...) __VA_ARGS__
#define N(...)
#define IF(x) x //alternate method similar to IFNOT()

#define NOT_N Y
#define NOT_Y N
#define IF_NOT(x) PASTE(NOT_,x)
#define NOT(x) PASTE(NOT_,x)

#define N_OR_N N
#define N_OR_Y Y
#define Y_OR_N Y
#define Y_OR_Y Y
#define OR(x,y) PASTE3(x,_OR_,y)

#define N_AND_N N
#define N_AND_Y N
#define Y_AND_N N
#define Y_AND_Y Y
#define AND(x,y) PASTE3(x,_AND_,y)

#define N_XOR_N N
#define N_XOR_Y Y
#define Y_XOR_N Y
#define Y_XOR_Y N
#define XOR(x,y) PASTE3(x,_XOR_,y)

#define N_NOR_N Y
#define N_NOR_Y N
#define Y_NOR_N N
#define Y_NOR_Y N
#define NOR(x,y) PASTE3(x,_NOR_,y)

#define N_NAND_N Y
#define N_NAND_Y Y
#define Y_NAND_N Y
#define Y_NAND_Y N
#define NAND(x,y) PASTE3(x,_NAND_,y)

#define N_XNOR_N Y
#define N_XNOR_Y N
#define Y_XNOR_N N
#define Y_XNOR_Y Y
#define XNOR(x,y) PASTE3(x,_XNOR_,y)

#define IF2(x,y,z) PASTE3(x,y,z)

config.h

#define FOO Y
#define BAR N
#define BAZ Y

code.c

AND(FOO,BAR)(/*do stuff if both FOO and BAR are enabled*/)
IF2(FOO,_AND_,BAR)( /*do stuff if both FOO and BAR are enabled*/ )
OR(BAZ,AND(FOO,BAR))(
  /*do stuff if both FOO and BAR are enabled or BAZ is enabled*/
)
3 голосов
/ 07 апреля 2011

Как вы упомянули, невозможно иметь #ifdef в #define. Вместо этого вам следует изменить порядок:

#ifdef COVERAGE_TOOL \
  #define COV_ON(x) \
    etc.
#endif
...