简体   繁体   中英

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

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_CLASS }

Using DEFAULT_NETWORK_TOKEN_KEY_CLASS macro only, how to get _ACD stringified in a const unsigned char [].

const uint8 startMsg[] = ?? DEFAULT_NETWORK_TOKEN_KEY_CLASS ;

Will result _ACD only.

What will be the correct macro expansion for getting _ACD here. In context of How to stringify macro having array as #define a_macro {5,7,7,97}?

(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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM