web-dev-qa-db-fra.com

#ifdef inside #define

J'essaie d'écrire quelque chose comme ça:

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

Existe-t-il un moyen de définir COV_ON comme ça? Je sais que ce que j'ai fait ci-dessus est faux car je ne peux pas avoir #ifdef à l'intérieur de #define. (# n'est pas un caractère autorisé dans #define). Y a-t-il une solution?

68
agent.smith

Pas possible. Faites-le dans l'autre sens:

#ifdef COVERAGE_TOOL
#define COV_ON(x) _Pragma (COVERAGE #x)
#else
#define COV_ON(x)
#endif
75
Hans Passant

Il suffit de le retourner:

#ifdef COVERAGE_TOOL
#define COV_ON(x) _Pragma (COVERAGE #x)
#else
#define COV_ON(x) /* foo */
#endif
21
Philip
#ifdef COVERAGE_TOOL
    #define COV_ON(x) _Pragma (COVERAGE #x)
#else
    #define COV_ON(x)
#endif
6
EboMike

Vous ne pouvez pas. Mais vous pouvez échanger #ifdef et #define:

#ifdef COVERAGE_TOOL
#   define COV_ON(x) _Pragma (COVERAGE #x)
#else
#   define COV_ON(x)
#endif
6
sam hocevar

C'est une vieille question, mais elle avait besoin d'une réponse à jour.

Au lieu d'utiliser un ifdef en ligne dans la macro, vous pouvez définir sélectivement une macro __VA_ARGS__ Pour faire la même chose

#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) )

Cela a des fonctionnalités similaires à un ifdef, sauf que vous obtenez des parenthèses pour délimiter le début et la fin (ce que la plupart des IDE n'ont pas de problèmes de pliage de code) Bien que vous puissiez toujours utiliser #define Et #ifdef Dans le contexte , #include N'est pas autorisé. Afin d'obtenir des capacités en ligne similaires à #else, Vous pouvez définir une macro correspondante comme celle-ci:

//#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
)

Un seul de NO_FOO()/IF_FOO produira du code.

OK, c'est un hack pratique, mais pouvons-nous le rendre PLUS utile que #ifdefs ... Logique booléenne et configuration peut-être? Permet de configurer des tables de vérité (et quelques macros d'assistance).

#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*/
)
5
technosaurus

Comme vous l'avez mentionné, il n'est pas possible d'avoir un #ifdef dans un #define. Ce que vous devez faire à la place, c'est inverser l'ordre:

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