没有空格的宏

Macro Without Space

本文关键字:空格      更新时间:2023-10-16

我有一个用于调试的宏。

#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并让它做我想做的事情呢?

您可以使用标记粘贴运算符##:

#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代表。

我隐约记得答案是类似的东西

//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有时需要两个宏(如我所示),因为我不太理解的奇怪原因,在C++faq 上解释了这一点