在C/C++预处理器中使用宏参数字符串化为宽字符串字面值

12

C语言预处理器有一个功能叫做字符串化。它允许从宏参数创建(窄)字符串字面量。可以像这样使用:

#define PRINTF_SIZEOF(x) printf("sizeof(%s) == %d", #x, sizeof(x))
/*                                  stringification ^^          */

使用示例:

PRINTF_SIZEOF(int);

...可能会打印:

sizeof(int) == 4

如何从宏参数创建一个宽字符串字面值?换句话说,我该如何实现 WPRINTF_SIZEOF?
#define WPRINTF_SIZEOF(x) wprintf( <what to put here?> )

2
自问自答没问题,但是这个问题在SO上已经被回答/讨论过很多次了。点击此处查看:https://dev59.com/CnVC5IYBdhLWcg3wrDNd - P.P
1
我实际上找不到重复项。 - Lightness Races in Orbit
@P.P. 我不明白你的观点。如果你认为提供的问题是重复的,我强烈反对。否则,请提供一个重复的链接。 - cubuspl42
你的问题并不是关于宽字符串,而是如何将两个标记放在一起。如果你搜索“标记连接”和“标记粘贴”,会有529和714个结果。我当然不想找到一个适合你的重复问题。但“重点”是,没有什么新的/有趣的东西需要发布新帖子(它只是SO上众多重复问题中的另一个)。 - P.P
我创建这个问题并不是为了获得虚拟奖励分,而是因为我在stackoverflow上找不到答案。我所关心的是在我正在开发的项目中将宏参数转换为宽字符串(我的环境缺乏窄字符printf)。我不知道答案是使用标记连接。你更有经验;你知道。但像“您的X问题毫无意义;您所需要做的就是搜索Y,其中Y是您的问题的答案”的论点是荒谬的。 - cubuspl42
1个回答

9
为了从宏参数中生成宽字符串字面量,您需要将字符串化与连接concatenation结合使用。 WPRINTF_SIZEOF可以定义为:
#define WPRINTF_SIZEOF(x) wprintf(L"sizeof(%s) == %d", L ## #x, sizeof(x))
/*                                         concatenation ^^ ^^ stringification */

为了(有争议地)增加可读性,您可以将此技巧提取为助手宏:
#define WSTR(x) L ## #x
#define WPRINTF_SIZEOF(x) wprintf(L"sizeof(%s) == %d", WSTR(x), sizeof(x))

顺便提一下,你可能想在那里加一个\n - Lightness Races in Orbit
2
在C和C++中,#define WSTR(x) L ## #x都是错误的,因为它依赖于未指定的行为:C11(J.1未指定的行为):_在宏替换期间评估#和##操作的顺序_,C ++,N4713(19.3.2#运算符):_#和##运算符的评估顺序未指定_。一种可能的正确实现是:#define CAT_(x,y) x ## y #define CAT(x,y) CAT_(x,y) #define STR_(x) #x #define STR(x) STR_(x) #define WSTR(x) CAT(L,STR(x)) - pmor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接