在 C/C++ 预处理器中将宏参数字符串化为宽字符串文字

cub*_*l42 9 c c++ string macros c-preprocessor

C 预处理器具有称为stringification的功能。这是一项允许从宏参数创建(窄)字符串文字的功能。它可以像这样使用:

#define PRINTF_SIZEOF(x) printf("sizeof(%s) == %d", #x, sizeof(x))
/*                                  stringification ^^          */
Run Code Online (Sandbox Code Playgroud)

用法示例:

PRINTF_SIZEOF(int);
Run Code Online (Sandbox Code Playgroud)

...可能会打印:

sizeof(int) == 4
Run Code Online (Sandbox Code Playgroud)

如何从宏参数创建字符串文字?换句话说,我该如何实施WPRINTF_SIZEOF

#define WPRINTF_SIZEOF(x) wprintf( <what to put here?> )
Run Code Online (Sandbox Code Playgroud)

cub*_*l42 9

为了从宏参数生成宽字符串文字,您需要将 stringification 与concatenation结合起来。

WPRINTF_SIZEOF 可以定义为:

#define WPRINTF_SIZEOF(x) wprintf(L"sizeof(%s) == %d", L ## #x, sizeof(x))
/*                                         concatenation ^^ ^^ stringification */
Run Code Online (Sandbox Code Playgroud)

为了(可以说)提高可读性,您可以将此技巧提取到辅助宏中:

#define WSTR(x) L ## #x
#define WPRINTF_SIZEOF(x) wprintf(L"sizeof(%s) == %d", WSTR(x), sizeof(x))
Run Code Online (Sandbox Code Playgroud)

  • 在 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))`. (3认同)