没有空间的宏

Ric*_*ard 4 c c++ macros printf widechar

我有一个用于调试的宏.

#define diagnostic_arg(message,...) fprintf(stderr,message,__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

我发现我需要在我的程序中使用宽字符,所以我想改变我的宏并让一切工作:

#define diagnostic_arg(message,...) fwprintf(stderr,message,__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

但是,我需要宽字符串,这是通过L在字符串的开头引号前面定义的:

#define diagnostic_arg(message,...) fprintf(stderr,Lmessage,__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

现在显然,上面的行不起作用.但如果我使用L message,那也无济于事.那么我该怎么写Lmessage并让它做我想做的事情呢?

Set*_*gie 14

您可以使用令牌粘贴运算符##:

#define diagnostic_arg(message,...) fprintf(stderr,L##message,__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

但是,使用TEXT宏(如果您在Visual Studio中)可能会更好,无论是否UNICODE定义,它都会做正确的事情:

#define diagnostic_arg(message,...) fprintf(stderr,TEXT(message),__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

如果你不是,TEXT可以这样定义:

#ifdef UNICODE
#define TEXT(str) L##str
#else
#define TEXT(str) str
#endif
Run Code Online (Sandbox Code Playgroud)

但是,如果你计划使用其他#defines作为这个宏的第一个参数(实际上即使你没有计划它),你需要在宏中另一层间接,这样定义将被评估而不是粘贴在一起与L文本.看看Mooing Duck的答案是如何做到的,他实际上是这样做的正确方法,但我没有删除这个答案,因为我想保留我的80名代表.


Moo*_*uck 7

我含糊地回忆起答案是有道理的

//glues two symbols together that can't be together
#define glue2(x,y) x##y
#define glue(x,y) glue2(x,y) 
//widens a string literal
#define widen(x) glue(L,x)

#define diagnostic_arg(message,...) fprintf(stderr,widen(message),__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

胶水有时需要是两个宏(正如我所示),因为我不太明白的原因,在C++ faq中解释