如何实现为 _Pragma 创建带引号的字符串的宏?
Posted
技术标签:
【中文标题】如何实现为 _Pragma 创建带引号的字符串的宏?【英文标题】:How do I implement a macro that creates a quoted string for _Pragma? 【发布时间】:2012-02-02 05:21:32 【问题描述】:我想要一个这样调用的宏:
GCC_WARNING(-Wuninitialized)
展开成这样的代码:
_Pragma("GCC diagnostic ignored \"-Wuninitialized\"")
我没有运气让它工作,因为预处理器连接和字符串化的常用技巧似乎不适用,或者我不知道如何在这里应用它们。
【问题讨论】:
【参考方案1】:在预处理器魔法的帮助下:
#define HELPER0(x) #x
#define HELPER1(x) HELPER0(GCC diagnostic ignored x)
#define HELPER2(y) HELPER1(#y)
#define GCC_WARNING(x) _Pragma(HELPER2(x))
GCC_WARNING(-Wuninitialized)
【讨论】:
谢谢,但这不起作用,可能是因为它没有将 \" 放在 -Wuninitialized 周围。上面的宏用法会产生以下 GCC 错误:忽略 #pragma GCC 诊断 [- Wunknown-pragmas] 它确实在 -Wuninitialized 周围加上引号。问题是一个错字diagnostics
而不是diagnostic
——我已经在上面的答案中修复了它。【参考方案2】:
如果宏参数用单引号括起来也可以接受吗?如果是这样,你可以使用这个:
#define GCC_WARNING(x) _Pragma("GCC diagnostic ignored '" #x "'")
当像 GCC_WARNING(-Wuninitialized)
这样调用它时,它会扩展为
_Pragma("GCC diagnostic ignored '" "-Wuninitialized" "'")
我必须在这里使用 C 的字符串连接行为(printf("a" "b");
与 printf("ab");
相同),因为在宏中使用 "'#x'"
可以避免 x
被扩展。
【讨论】:
几乎...实际上“_Pragma”对gcc有特殊含义。我发布了一个类似的解决方案,但我意识到它不适用于我的 gcc,因为预处理器会抱怨(“错误:_Pragma 需要带括号的字符串文字”)。 那行不通——_Pragma
在字符串连接之前解释它的参数,所以它会看到两个字符串,而不是一个。与printf
不同,它是一个遵循特殊规则的特殊构造。
啊,多么愚蠢,我没想到这是一个 GCC 特定的问题。我以为_Pragma
是一些自定义调试功能,但现在我看一下宏的名称,我应该更清楚。
事实上 _Pragma
不是 GCC 特定的。它是 C99 标准的一部分,允许宏扩展为 pragma。但是,用户询问了特定于 GCC 的用例,但该问题对于通用 pragma 仍然有效。
@Lindydancer:有趣!我什至没有意识到它是 C99 标准的一部分。今天学到了新东西。 :-)以上是关于如何实现为 _Pragma 创建带引号的字符串的宏?的主要内容,如果未能解决你的问题,请参考以下文章