没有空间的宏

时间:2012-03-21 21:18:24

标签: c++ c macros printf widechar

我有一个用于调试的宏。

#define diagnostic_arg(message,...) fprintf(stderr,message,__VA_ARGS__)

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

#define diagnostic_arg(message,...) fwprintf(stderr,message,__VA_ARGS__)

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

#define diagnostic_arg(message,...) fprintf(stderr,Lmessage,__VA_ARGS__)

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

2 个答案:

答案 0 :(得分:14)

您可以使用token pasting operator ##

#define diagnostic_arg(message,...) fprintf(stderr,L##message,__VA_ARGS__)

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

#define diagnostic_arg(message,...) fprintf(stderr,TEXT(message),__VA_ARGS__)

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

#ifdef UNICODE
#define TEXT(str) L##str
#else
#define TEXT(str) str
#endif

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

答案 1 :(得分: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__)

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