【问题标题】:Selectively disable GCC warnings for only part of a translation unit仅针对部分翻译单元有选择地禁用 GCC 警告
【发布时间】:2010-11-01 04:39:42
【问题描述】:

与此 MSVC 预处理器代码最接近的 GCC 是什么?

#pragma warning( push )                    // Save the current warning state.
#pragma warning( disable : 4723 )          // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop )                     // Restore warnings to previous state.

我们在通常包含的标头中有代码,我们不想为其生成特定警告。但是,我们希望包含这些标头的文件继续生成该警告(如果项目启用了该警告)。

【问题讨论】:

  • 如果头文件安装到 /usr/include 或者你有什么 gcc 默认不会为它们生成警告。

标签: c++ c gcc compiler-warnings pragma


【解决方案1】:

这是possible in GCC,自 4.6 版起,或 2010 年 6 月左右在后备箱中。

这是一个例子:

#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop
    foo(d);         /* depends on command line options */

【讨论】:

  • 在 gcc 4.6 (gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html) 中添加了推送和弹出功能。
  • 如果您要弹出两次,您可能需要推送两次。
  • @Dan:阅读手册并发表评论。请注意示例的出处。
  • 仅供参考 older versions like 4.4.7 您仍然可以使用 #pragma GCC diagnostic [error|warning|ignored]pop 未实现/支持。
  • 有没有办法通过这个方法禁用一段代码的所有警告?
【解决方案2】:

最接近的是GCC diagnostic pragma#pragma GCC diagnostic [warning|error|ignored] "-Wwhatever"。它与您想要的不太接近,请参阅链接了解详细信息和注意事项。

【讨论】:

  • 您知道不添加此功能的原因和原因是什么吗? (我找不到它。)我发现警告 push-disable-pop 很有用。
  • 我真的不认为向 gcc “不添加功能”往往有一个理由,就像没有人提交工作补丁一样。
  • 并不是没有人愿意在 gcc 中为这种细粒度的警告控制做这项工作,或者提交代码——我知道一个主要的硅谷公司已经这样做了,另一个那会很高兴付钱给某人去做并将代码放入流中。相反,根据与(作为 gdb 维护者之一)插入这些东西的人的讨论,gcc 维护者有一个理念:“如果有警告,那就是错误,你需要修复它。”所以(imo)这是一个宗教论点,他们控制代码所以他们赢了。
  • 补充 Bob 的评论,GCC 开发人员有不喜欢 #pragma 指令的历史,因此任何特定于 GCC 的东西都可能更可能被实现为 __attribute__((foo))。跨度>
  • 新 gcc (>=4.4) 具有 #pragma GCC push_options,因此您可以处理的不仅仅是诊断...gcc.gnu.org/onlinedocs/gcc/…
【解决方案3】:

我做过类似的事情。对于第三方代码,我根本不想看到任何警告。所以,我没有指定-I/path/to/libfoo/include,而是使用-isystem /path/to/libfoo/include。这使得编译器出于警告的目的将这些头文件视为“系统头文件”,只要您不启用-Wsystem-headers,您基本上是安全的。我仍然看到一些警告从那里泄露出来,但它减少了大部分垃圾。

请注意,如果您可以通过包含目录隔离违规代码,则此可以帮助您。如果它只是您自己项目的一个子集,或者与其他代码混合在一起,那么您就不走运了。

【讨论】:

  • 很棒的提示。如果使用 LLVM,请在“Apple LLVM 编译器 - 语言”部分的“其他 C 标志”下添加 -isystem 标志。
  • @Tom 感谢分享。我不明白在哪里使用您的解决方案。能不能多说一点?
【解决方案4】:

这是对Matt Joiner's answer 的扩展。

如果您不想在整个代码中生成编译指示,可以使用_Pragma operator

#ifdef __GNUC__
#  define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
#  define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
#  define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#  define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)

DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error

DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error

DIAGNOSTIC_POP
foo(a); // Error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-22
    • 2010-11-29
    • 1970-01-01
    • 2010-10-21
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多