如何抑制库标头中的 GCC 警告?

How to suppress GCC warnings from library headers?

提问人:AdSR 提问时间:12/8/2009 更新时间:2/3/2021 访问量:65318

问:

我有一个使用 log4cxx、boost 等库的项目,其标头会生成大量(重复)警告。有没有办法禁止来自库包含(即 #include < some-header.h>)或来自某些路径的包含的警告?我想像往常一样在项目代码上使用 -Wall 和/或 -Wextra,而不会掩盖相关信息。我目前在make输出上使用grep,但我想要更好的东西。

GCC 抑制-警告 GCC 警告

评论


答:

4赞 Pablo Santa Cruz 12/8/2009 #1

您可以尝试使用预编译的标头。警告不会消失,但至少不会出现在您的主编译中。

评论

1赞 AdSR 12/8/2009
这实际上可能是一个好主意。第三方包含不会每天都更改。
0赞 Pablo Santa Cruz 12/8/2009
完全。虽然我在 Linux 中没有经常使用它们,但它们在 Visual Studio 上运行得很好。
0赞 user202729 11/13/2019
不,它们仍然会出现在编译中,除非你使用其他方式来抑制它们(例如,但请记住在编译标头和代码中都使用它)-isystem
9赞 Hassan Syed 12/8/2009 #2

#pragma是编译器的指令。您可以在 #include 之前设置某些内容,然后在之后禁用它。

您也可以在命令行中执行此操作。

另一个专门关于禁用警告的 GCC 页面。

我会选择在源代码中使用 #pragma,然后提供一个合理的理由(作为评论)来说明您为什么要禁用警告。这意味着对头文件进行推理。

GCC 通过对警告类型进行分类来实现此目的。您可以将它们分类为警告或忽略。之前链接的文章将向您显示哪些警告可能被禁用。

注意:您还可以使用属性来修改源代码以防止某些警告;但是,这使您与 GCC 紧密相连。

注意2:GCC还使用Microsoft编译器中使用的pop/push接口 - Microsoft通过此接口禁用警告。我建议你进一步调查这个问题,因为我不知道这是否可能。

评论

1赞 AdSR 12/8/2009
我考虑过编译指示,但是如果我在包含标头之前禁止显示警告,那么在 #include 后如何将其设置回以前的状态?我想查看项目代码的所有警告(已经帮助了我几次),但可以从命令行进行控制。
-10赞 anon 12/8/2009 #3

这些警告一定是有原因的。这些错误可能是由使用库的代码中的错误引起的,也可能是由库代码本身的错误引起的。在第一种情况下,修复代码。在第二种情况下,要么停止使用该库,要么如果它是 FOSS 代码,请修复它。

评论

0赞 Hassan Syed 12/8/2009
+1 提供好的建议:D但他在问如何做一些具体的事情:D
6赞 ulidtko 8/5/2011
有些警告是不可能或很难修复的,尤其是在第三方代码中,尤其是在像 Boost 这样富含元编程的代码中。
3赞 dmckee --- ex-moderator kitten 11/17/2011
更糟糕的是,困扰我的是“声明'c'阴影''this'的成员 [-Werror=shadow]”,深入到某个提升标头中。这当然不是问题,但它和类似的问题正在喷出输出,使我很难在我们的代码库中找到真正的阴影实例。
35赞 AdSR 12/14/2009 #4

我找到了诀窍。对于库包含,而不是在 makefile 中使用。然后,GCC 将 boost 等视为系统包含并忽略来自它们的任何警告。-Idir-isystem dir

评论

1赞 user202729 11/13/2019
请注意,如果使用预编译标头,则需要在编译标头和代码时添加标志。
147赞 Phi 12/14/2009 #5

您可以尝试使用 而不是 来包含库头文件。这将使它们成为“系统标头”,GCC 不会报告它们的警告。-isystem-I

评论

11赞 Matt Parkins 12/11/2013
如果您尝试在 XCode 中执行此操作,请将 -isystem 路径粘贴到目标构建设置中“自定义编译器标志”中的“其他 C++ 标志”中。
5赞 Tavian Barnes 2/23/2016
一个潜在的缺点是,在某些平台上,g++ 会自动将任何系统头文件包装在 中,如果您在路径中使用 C++ 头文件,则会导致有关 C 链接的奇怪错误。extern "C"#include-isystem
1赞 mrgloom 3/1/2016
+1 帮助我解决了烦人的提升警告问题 stackoverflow.com/questions/35704753/warnings-from-boost
3赞 underscore_d 7/22/2016
为什么这比 OP 自己的答案多得多,而 OP 在 1.5 小时前说了完全相同的话?
1赞 Ossir 10/13/2016
对于 Xcode:如果目标构建设置中的“其他 C++ 标志”中没有文件夹路径,该怎么办?有人可以详细说明这个解决方案吗?
67赞 andrewrjones 11/21/2012 #6

您可以使用编译指示。例如:

// save diagnostic state
#pragma GCC diagnostic push 

// turn off the specific warning. Can also use "-Wall"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>

// turn the warnings back on
#pragma GCC diagnostic pop

评论

3赞 Caduchon 5/19/2015
仅适用于 GCC >= 4.6
1赞 Trevor Boyd Smith 3/31/2018
我喜欢推送/弹出编译指示的能力。我记得几年前可用的 Java 和 C/C++ 的沮丧/嫉妒。我喜欢这在gcc
1赞 Alexis Wilke 5/16/2020
@TrevorBoydSmith MS多年来也一直拥有这种能力......有时适应起来有点慢。clgcc
2赞 luator 1/28/2021
似乎您只能一个接一个地禁用警告,即 不起作用。请参阅相关问题-Wall
149赞 Drew Noakes 10/10/2014 #7

对于使用 CMake 的用户,您可以修改指令以包含禁止针对此类标头的警告的符号。include_directoriesSYSTEM

include_directories(SYSTEM "${LIB_DIR}/Include")
                    ^^^^^^

评论

1赞 waldyrious 10/7/2016
如果库提供了一个要与 CMake 的 include() 命令一起使用的变量,该怎么办?${LIBFOO_USE_FILE}
2赞 knedlsepp 10/11/2016
这似乎几乎是我问题的解决方案。我有 1 个。一个二进制目标,它依赖于 2。我自己写的 header only target,取决于 3.)一些外部库。我不知道如何只收到 1 和 2 的警告。你有什么想法吗?
2赞 rbaleksandar 3/2/2018
似乎不起作用。我尝试过一个使用的项目,即使它所在的文件夹已包含在选项中,我也收到了同样大量的警告。easylogging++easylogging++.hSYSTEM
0赞 Svalorzen 3/21/2018
非常感谢。它把我从一页又一页的警告中拯救出来。
1赞 Raffi 9/21/2018
与接受的答案相同的评论:这对我来说是不好的做法。
2赞 supaflav 2/9/2015 #8

如果需要显式重写系统标头,则只能使用编译指示。您可以通过输出验证您正在使用的包含。make depend

另请参阅 gcc >= 4.6 的诊断 push-pop

6赞 Evgenii 7/4/2019 #9

把以下内容

#pragma GCC system_header

将关闭此文件中所有以下代码的 GCC 警告。

0赞 DianaNowa 2/3/2021 #10

另一种方法是,在 makefile 中,告诉编译器忽略特定文件夹的警告:

$(BUILD_DIR)/libs/%.c.o: CFLAGS += -w

评论

0赞 user686249 2/3/2021
这将禁止显示所有警告,而不仅仅是外部库标头中的警告,这很可能是不需要的。