C++ 是否仅对翻译单元的一部分选择性禁用GCC警告?

C++ 是否仅对翻译单元的一部分选择性禁用GCC警告?,c++,c,gcc,compiler-warnings,pragma,C++,C,Gcc,Compiler Warnings,Pragma,与此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 )

与此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.

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

最接近的是,
\pragma GCC diagnostic[warning | error | ignored]“-Wwhatever”
。它与您想要的不是很接近,请查看链接了解详细信息和注意事项。

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

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

这是从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 */
这是对的扩展

如果不想在代码中产生杂注,可以使用:


您知道不添加此功能的理由是什么吗?(我找不到。)我发现警告push disable pop很有用。我真的不认为“不向gcc添加功能”会有一个理由,以至于没有人提交工作补丁。这并不是说没有人愿意在gcc中为这种细粒度警告控制做工作,或者提交代码——据我所知,有一家硅谷大公司已经这样做了,还有一家公司会很乐意花钱让人来做,并将代码输入流中。相反,根据与一位(作为gdb维护者之一)参与这项工作的人的讨论,gcc维护者有一个理念:“如果有警告,那就是一个bug,你需要修复它。”因此(依我看),这是一个宗教论点,他们控制代码,所以他们赢了。为了补充Bob的评论,GCC开发人员一直不喜欢
#pragma
指令,因此任何特定于GCC的东西都可能被实现为
uu属性(foo))
。新的GCC(>=4.4)具有
#pragma GCC push_选项
,因此您可以处理的不仅仅是诊断。。。如果标题安装到/usr/include或其他位置,默认情况下,gcc不会为其生成警告。推送和弹出功能是在gcc 4.6()中添加的。如果要弹出两次,您可能需要推送两次。@Dan:阅读手册并发表评论。请注意example.FYI的来源,因为您仍然可以使用
#pragma GCC诊断[错误|警告|忽略]
,但未实现/支持
pop
。很棒的提示。如果使用LLVM,请在“Apple LLVM编译器-语言”部分的“其他C标志”下添加-isystem标志。@Tom感谢分享。我不明白在哪里使用你的解决方案。你能再说一点吗?
#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