#ifdef inside #define

前端 未结 6 1853
情书的邮戳
情书的邮戳 2020-11-29 02:31

I am trying to write something like this:

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


        
相关标签:
6条回答
  • 2020-11-29 03:04

    Simply turn it around:

    #ifdef COVERAGE_TOOL
    #define COV_ON(x) _Pragma (COVERAGE #x)
    #else
    #define COV_ON(x) /* foo */
    #endif
    
    0 讨论(0)
  • 2020-11-29 03:13

    Not possible. Do it the other way around:

    #ifdef COVERAGE_TOOL
    #define COV_ON(x) _Pragma (COVERAGE #x)
    #else
    #define COV_ON(x)
    #endif
    
    0 讨论(0)
  • 2020-11-29 03:16

    This is an old question, but it needed an up to date answer.

    Instead of using an inline ifdef within the macro you can selectively define a __VA_ARGS__ macro to do the same thing

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

    This has similar functionality to an ifdef except that you get parentheses to delineate the beginning and end (which most IDEs have no problems code-folding) While you can still use #define and #ifdef within the context, #include is not allowed. In order to get inline capabilities similar to #else, you can define a corresponding macro like this:

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

    Only one of NO_FOO()/IF_FOO will produce code.

    OK, that's a handy hack, but can we make it MORE useful than #ifdefs... Boolean logic and configuration perhaps? Lets set up some truth tables (and a couple helper macros).

    #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*/
    )
    
    0 讨论(0)
  • 2020-11-29 03:17

    As you mentioned it is not possible to have an #ifdef in a #define. What you should do instead is reverse the order:

    #ifdef COVERAGE_TOOL \
      #define COV_ON(x) \
        etc.
    #endif
    
    0 讨论(0)
  • 2020-11-29 03:20
    #ifdef COVERAGE_TOOL
        #define COV_ON(x) _Pragma (COVERAGE #x)
    #else
        #define COV_ON(x)
    #endif
    
    0 讨论(0)
  • 2020-11-29 03:25

    You cannot. But you can swap #ifdef and #define:

    #ifdef COVERAGE_TOOL
    #   define COV_ON(x) _Pragma (COVERAGE #x)
    #else
    #   define COV_ON(x)
    #endif
    
    0 讨论(0)
提交回复
热议问题