【问题标题】:How to disable a particular unknown #pragma warning (GCC and/or Clang)如何禁用特定的未知#pragma 警告(GCC 和/或 Clang)
【发布时间】:2011-09-27 06:35:22
【问题描述】:

我知道如何禁用所有未知的#pragma 警告。例如,在 How can I disable #pragma warnings? 中给出了答案。

有没有办法为一个特定的编译指示禁用“未知编译指示”警告?例如,如果我禁用 #pragma ugubugu 的警告,则以下代码:

#pragma ugubugu
#pragma untiunti

int main() {return 0;}

当编译时:

g++ pragma.cpp -Wall
clang++ pragma.cpp -Wall

应该产生一个警告:

warning: ignoring #pragma untiunti

例如,也许有一种简单的方法来注册一个什么都不做的自定义编译指示?

很高兴知道 Visual Studio 是否也有这样的选项,但这并不重要。


“但他最终为什么要玩自定义编译指示?”

我的源代码由两个编译器解析。在其中一个中,有一个特殊的#pragma 是另一个未知的。当然,我可以将#ifdef COMPILER_IDENTIFICATION_MACRO ... #endif 放在#pragma 的每个实例周围,但这会很麻烦。

【问题讨论】:

    标签: c++ gcc clang


    【解决方案1】:
    • 编译器不允许自定义编译指示,因为编译指示(大部分)是编译器和/或链接器控制指令。由于这非常接近特定的编译器实现和特性,那么为用户“定义新的 pragma”的应用程序是什么?事实上,在特定编译器上实现的可用 pragma 指令完全独立于供应商(没有 C++ 标准化规则)。
    • 您可能希望使用编译指示来标记代码的特殊部分(例如,提供您自己的预处理器),因为您要求的是无操作指令。这可以使用预处理器 (#defines) 完成。
    • 在 C/C++ 代码中自定义“标记”的另一种可能性,例如 #MY_PRAGMA,是在 C/C++ 代码之前使用您自己的预处理器。

    此类处理的一个示例用于Qt 库,这是与 Qt MOC 编译器交互的非标准元对象系统。这用于扩展一些非 C++ 结构(例如,Q_OBJECT、Q_PROPERTY 等),这些结构随后会以有效语法提供给 C++ 编译器。

    【讨论】:

    • 我不认为他正在寻找一个什么都不做的编译指示,而是他认为这是一种可能的方式来消除警告。 ugubugu 是一个未知的 pragma,所以注册它,但让它什么都不做,所以现在它是一个不会产生警告的已知 pragma。
    • @Dennis Zickefoose,但为什么他最终会使用自定义编译指示?我怀疑他正试图将它们用作代码中的“标记”或类似的东西,这是完全有效的,但有替代方法而不是使用您自己的编译指示(这可能与编译器供应商的编译指示冲突,因为它们没有标准化)
    【解决方案2】:

    我假设您想禁用编译指示警告,因为它在一个平台上有效,但在另一个平台上无效。如果是这种情况,您可以使用宏来选择性地启用 pragma,从而无需抑制警告。

    例如,如果您只需要 Visual C++ 上的编译指示,您可以这样做:

    #if defined(_MSC_VER)
    #    define SAFE_PRAGMA_UGUBUGU __pragma(ugubugu)
    #else
    #    define SAFE_PRAGMA_UGUBUGU 
    #endif
    

    然后,你可以写

    SAFE_PRAGMA_UGUBUGU
    #pragma untiunti   
    int main() {return 0;}
    

    【讨论】:

      【解决方案3】:

      我有理由确定没有任何方法可以做到这一点。

      GCC 和 Clang 都有内部接口,允许语言前端向预处理器注册 #pragma 处理程序 - 参见 GCC 的 libcpp/directives.c 和 Clang 的 lib/Lex/Pragma.cpp - 但是,据我所知,没有什么可以允许您根据命令行选项修改注册的处理程序(超出您正在编译的语言变体所暗示的内容)。

      我知道如何禁用所有未知的#pragma 警告。例如,这里给出了答案:SO: How to disable #pragma warnings?

      请注意,投票最高的答案比那里接受的答案要好。 -Wno-unknown-pragmas 可以简单地添加到命令行之后 任何可以打开警告的内容(如-Wall)。

      我的源代码由两个编译器解析。在其中一个中,有一个特殊的#pragma,另一个未知。当然,我可以将#ifdef COMPILER_IDENTIFICATION_MACRO ... #endif 放在#pragma 的每个实例周围,但这会很麻烦。

      从更哲学的角度来看,我认为这确实是正确的解决方案,尽管它可能很麻烦!

      考虑到#pragma 的全部意义在于提供一种调用实现定义的机制,我认为从编译器中隐藏任何#pragma 似乎是正确的编译器中的行为。

      (如果您最终这样做,请注意 Clang 定义了 __clang__,但GCC 和 Clang 都定义了 __GNUC__。)

      【讨论】:

      • 鉴于没有人提供更好的解决方案,我不得不接受“现在有办法做到这一点”的说法——那就是——你的。此外,如果我决定更深入地了解它,指向编译器内部的指针可能会有所帮助。谢谢!
      • 没有人知道在代码中抑制警告的方法吗?当我提交它时,它会上升到我无法控制的自动化项目生成。它在构建时带有完整的警告。
      • #pragma GCC 诊断推送 #pragma GCC 诊断忽略“-Wunknown-pragmas” ... 使用未知 pragmas 的代码 ... #pragma GCC 诊断推送
      • @Dan 上面关于使用#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunknown-pragmas" 的注释是一个可行的解决方案,如果你愿意以这种方式包围你未知的#pragmas;只是用#pragma GCC diagnostic pop 而不是#pragma GCC diagnostic push 来关闭它。我在我的代码中使用#pragma mark 语句是为了让我的 IDE 受益,而 GCC 正在发出警告,因为这是我想要阻止的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-10
      • 1970-01-01
      • 2010-11-07
      相关资源
      最近更新 更多