如何实现为 _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 创建带引号的字符串的宏?的主要内容,如果未能解决你的问题,请参考以下文章

CMake系列:添加有空格不带引号的宏定义

C++ 一种禁止方法被使用的宏

C++ 一种禁止方法被使用的宏

C++ 一种禁止成员方法被使用的宏

如何在 R 中显示带引号的文本? [复制]

C语言宏定义实现可变参数