没有空间的宏
Posted
技术标签:
【中文标题】没有空间的宏【英文标题】:Macro Without Space 【发布时间】:2012-04-06 11:14:00 【问题描述】:我有一个用于调试的宏。
#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
并让它做我想做的事呢?
【问题讨论】:
【参考方案1】:您可以使用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
s 作为此宏的第一个参数(实际上即使您不打算这样做),您将需要另一层间接在宏中,因此将评估定义而不是与L
一起作为文本粘贴。请参阅 Mooing Duck 的答案以了解如何做到这一点,他实际上是正确的方法,但我不会删除这个答案,因为我想保留我的 80 代表。
【讨论】:
只要意识到TEXT()
宏是微软的东西——我认为它在非 Windows 世界中并不常见(但也许我错了)。无论如何,实现自己很容易。
@MichaelBurr 我认为L
也是微软的东西,不是吗?
@Seth:不,L
前缀是标准 C 和 C++。它创建了一个 wchar_t[]
类型的文字。【参考方案2】:
我隐约记得答案类似于
//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__)
胶水有时需要是两个宏(如我所示),出于奇怪的原因,我不太明白,解释at the C++faq
【讨论】:
当然,Seth Carnegie 的回答要直截了当,我不知道为什么我没有想到直接的路线。 我也记得类似的东西,但我不记得什么时候需要它了。 啊,这里是:parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 这样你就可以在那里使用其他#define
s。这个答案其实是正确的。
如果message
参数中传递的是宏本身,您需要额外的间接寻址。
我很欣赏它的技术正确性。不过,@SethCarnegie 的回答在我的使用场景中似乎效果很好。谢谢你们。以上是关于没有空间的宏的主要内容,如果未能解决你的问题,请参考以下文章