有选择地仅对翻译单元的一部分禁用GCC警告吗?


85

与此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,则默认情况下不会为它们生成警告。
Spudd86 2010年

Answers:


95

自4.6版以来,这在GCC中可能的,或者在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 */

8
推送和弹出功能已在gcc 4.6(gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html)中添加。
戴夫·约翰森

如果您要弹出两次,则可能要按两次。
2014年

2
@丹:阅读手册,并发表评论。注意示例的来源。
马特·乔纳

仅供参考,例如4.4.7的旧版本,您仍然可以使用,#pragma GCC diagnostic [error|warning|ignored]pop尚未实现/不支持。
Trevor Boyd Smith,

36

最接近的是GCC诊断语用#pragma GCC diagnostic [warning|error|ignored] "-Wwhatever"。它与您想要的不是很接近,请查看链接以获取详细信息和警告。


1
您知道不添加此功能的理由和理由是什么?(我找不到它。)我发现警告push-disable-pop很有用。

1
我真的没有想到gcc的“不添加功能”往往有一个基本原理,就像没有人提交工作补丁一样。
混乱

14
不是有人愿意在gcc中进行这种细粒度的警告控制,或者是提交代码-我知道一家主要的硅谷公司已经做到了,而另一家很乐意付钱给某人为此,并将代码放入流中。相反,与一个(作为gdb维护者之一)插入其中的家伙进行的讨论中,gcc维护者有一个哲学:“如果有警告,那是一个错误,您需要对其进行修复。” 因此(imo)是一个宗教争论,他们控制代码以致取胜。
鲍勃·墨菲

值得一提的是,GCC开发人员有一个不喜欢该#pragma指令的历史,因此,特定于GCC的所有内容都可能会被实现为__attribute__((foo))
汤姆(Tom)2010年

10
新的海湾合作委员会(> = 4.4)的#pragma GCC push_options,所以你可以胡闹的不仅仅是诊断更多... gcc.gnu.org/onlinedocs/gcc/...
Spudd86

33

我做了类似的事情。对于第三方代码,我根本不想看到任何警告。因此,-I/path/to/libfoo/include我使用而不是指定-isystem /path/to/libfoo/include。这使编译器出于警告目的将这些头文件视为“系统头”,并且只要您不启用-Wsystem-headers,大多数情况下都是安全的。我仍然看到一些警告从那里泄漏出来,但是它减少了大多数垃圾。

请注意,这在可以通过include-directory隔离有问题的代码时才有帮助。如果它只是您自己的项目的一个子集,或者与其他代码混合在一起,那么您就不走运了。


1
大提示。如果使用LLVM,请在“ Apple LLVM编译器-语言”部分的“其他C标志”下添加-isystem标志。
Nestor 2012年

@Tom感谢您的分享。我不知道在哪里使用您的解决方案。你能说更多吗?
Lorenzo B

1

这是对Matt Joiner答案的扩展。

如果不想在整个代码中产生编译指示,则可以使用_Pragma运算符

#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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.