宏扩展和字符串化:如何使用另一个宏来解析宏名称(而不是它的值)?

不感兴趣:

#define _ACD 5, 5, 5, 30 #define DEFAULT_NETWORK_TOKEN_KEY_CLASS _ACD #define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS } 

仅使用DEFAULT_NETWORK_TOKEN_KEY_CLASS宏,如何在const unsigned char []中获取字符串化的_ACD。

 const uint8 startMsg[] = ?? DEFAULT_NETWORK_TOKEN_KEY_CLASS ; 

只会导致_ACD

在这里获取_ACD的正确宏扩展是什么? 在如何将具有数组的宏字符串化为#define a_macro {5,7,7,97}的上下文中?

(关于在没有充分理由的情况下不滥用C预处理器的标准免责声明适用于此。)

你当然可以做你想做的事。 您需要一个STRINGIFY宏和一些宏间接。

通常, STRINGIFY定义为一个间接级别,以允许C预处理器在进行字符串化之前扩展其参数。 一个实现是:

 /* The # operator converts symbol 'v' into a string */ #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; 

在这里, STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)扩展为STRINGIFY0(5,5,5,30) ,C预处理器抱怨你给STRINGIFY0太多参数。

解决方案是延迟_ACD的扩展,以便在需要时扩展到5,5,5,30 。 为此,请将其定义为类似函数的宏:

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

这样,只有在“调用”它时才会扩展_ACD()_ACD()DEFAULT_NETWORK_TOKEN_KEY_CLASS现在将扩展为_ACD ,您必须通过“调用”它来进一步扩展它: DEFAULT_NETWORK_TOKEN_KEY_CLASS()

以下代码说明了解决方案:

 #include  #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; }