(关于在没有充分理由的情况下不得滥用 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;
Here, 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 <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;
}