6

我有一个用于调试的宏。

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

4

2 回答 2

16

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

#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

但是,如果您打算使用 other #defines 作为此宏的第一个参数(实际上即使您不打算这样做),您将需要在宏中添加另一层间接,以便对定义进行评估而不是粘贴在一起L作为文本。请参阅 Mooing Duck 的答案以了解如何做到这一点,他实际上是这样做的正确方法,但我不会删除这个答案,因为我想保留我的 80 代表。

于 2012-03-21T21:20:50.353 回答
8

我隐约记得答案类似于

//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 中进行了解释

于 2012-03-21T21:21:20.000 回答