Це давнє запитання, але воно вимагало актуальної відповіді.
Замість використання вбудованого 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, за винятком того, що ви отримуєте дужки для розмежування початку та кінця (що у більшості середовищ розроблення середовища не має проблем зі складанням коду). Хоча ви все ще можете використовувати #define
і #ifdef
в контексті, #include
не дозволяється. Для того, щоб отримати вбудовані можливості, подібні до #else
, ви можете визначити відповідний макрос таким чином:
#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
видасть код.
Добре, це зручний хак, але чи можемо ми зробити це БІЛЬШ корисним, ніж #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
#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
код. c
AND(FOO,BAR)()
IF2(FOO,_AND_,BAR)( )
OR(BAZ,AND(FOO,BAR))(
)
do {} while(0)
(або еквівалент), щоб уникнути порожнього твердження; див. мою відповідь на зв’язаний дублікат