Macro expansion and stringification: How to get the macro name (not its value) stringified using another macro?

后端 未结 1 1848
耶瑟儿~
耶瑟儿~ 2020-12-03 12:28

Out of interest:

#define _ACD 5, 5, 5, 30

#define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 

#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLA         


        
相关标签:
1条回答
  • 2020-12-03 12:51

    (The standard disclaimer about not abusing the C preprocessor without a really good reason applies here.)

    It's certainly possible to do what you want to do. You need a STRINGIFY macro and a bit of macro indirection.

    Typically, STRINGIFY is defined with one level of indirection, to allow the C preprocessor to expand its arguments before they undergo stringification. One implementation is:

    /* The # operator converts symbol 'v' into a string */
    #define STRINGIFY0(v) #v
    #define STRINGIFY(v) STRINGIFY0(v)
    

    However, you'll find that this isn't enough:

    #define _ACD 5, 5, 5, 30
    #define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 
    #define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS }
    
    #define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)
    const char startMsg[] = START_MSG;
    

    Here, STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS) expands to STRINGIFY0(5,5,5,30), and the C preprocessor complains that you've given STRINGIFY0 too many arguments.

    The solution is to delay the expansion of _ACD so it only expands to 5,5,5,30 when you want it to. To do this, define it as a function-like macro:

    #define _ACD() 5, 5, 5, 30
    

    This way, _ACD will only be expanded when you "call" it: _ACD(). DEFAULT_NETWORK_TOKEN_KEY_CLASS will now expand to _ACD, and you have to expand it further by "calling" it: DEFAULT_NETWORK_TOKEN_KEY_CLASS().

    The following code illustrates the solution:

    #include <stdio.h>
    
    #define STRINGIFY0(v) #v
    #define STRINGIFY(v) STRINGIFY0(v)
    
    #define _ACD() 5, 5, 5, 30
    #define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 
    #define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS() }
    
    #define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)
    
    const char startMsg[] = START_MSG;
    
    int main(int argc, char** argv)
    {
      printf("%s\n",startMsg);
      return 0;
    }
    
    0 讨论(0)
提交回复
热议问题