没有空间的宏

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

但是,如果您打算使用其他 #defines 作为此宏的第一个参数(实际上即使您不打算这样做),您将需要另一层间接在宏中,因此将评估定义而不是与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 这样你就可以在那里使用其他#defines。这个答案其实是正确的。 如果message 参数中传递的是宏本身,您需要额外的间接寻址。 我很欣赏它的技术正确性。不过,@SethCarnegie 的回答在我的使用场景中似乎效果很好。谢谢你们。

以上是关于没有空间的宏的主要内容,如果未能解决你的问题,请参考以下文章

打开wps的宏设置,提示你可能没有装vba

带参数的宏替换

有没有一种方法可以将宏名称作为参数传递给嵌套宏,而不会在扩展最外层的宏时扩展它们?

在excel中显示/隐藏状态栏的宏

SAS:包括输出中的宏参考? [重复]

驱动中的宏定义及预编译指令