【问题标题】:How to suppress GCC warnings from library headers?如何抑制库头文件中的 GCC 警告?
【发布时间】:2010-12-24 10:27:19
【问题描述】:

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

【问题讨论】:

    标签: gcc warnings suppress-warnings gcc-warning


    【解决方案1】:

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

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

    【讨论】:

    • 这会禁止所有警告,而不仅仅是外部库标头中的警告,这很可能是不需要的。
    【解决方案2】:

    把下面的

    #pragma GCC system_header
    

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 注意,如果你使用预编译的头文件,你需要在编译头文件和代码时添加标志。
      【解决方案4】:

      如果您需要显式覆盖系统标头,则只能使用编译指示。您可以通过make depend 输出验证您正在使用的包括哪些内容。

      另见diagnostic push-pop for gcc >= 4.6

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 如果库提供了一个${LIBFOO_USE_FILE} 变量以用于CMake 的include() 命令怎么办?
        • 这似乎几乎可以解决我的问题。我有 1.) 一个二进制目标,它取决于 2.) 我自己编写的仅标头目标,这取决于 3.) 一些外部库。我不知道如何只获得 1&2 的警告。你有什么想法吗?
        • 似乎不起作用。我在一个使用easylogging++ 的项目中尝试了这个,我从easylogging++.h 收到了同样大量的警告,即使它所在的文件夹已包含在SYSTEM 选项中。
        • 非常感谢。它使我免于一页又一页的警告。
        • 与接受的答案相同的评论:这对我来说是不好的做法。
        【解决方案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
        

        【讨论】:

        • 仅适用于 GCC >= 4.6
        • 我喜欢 push/pop pragma 的能力。我记得几年前可用的 java 之类的东西,并且对 C/C++ 感到沮丧/嫉妒。我喜欢 gcc
        • @TrevorBoydSmith MS cl 也有多年的能力......有时gcc 适应起来有点慢。
        • 看来只能一个一个禁用警告,即-Wall不起作用。见related question
        【解决方案7】:

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

        【讨论】:

        • 如果您尝试在 XCode 中执行此操作,则将 -isystem 路径粘贴到目标构建设置中“自定义编译器标志”中的“其他 C++ 标志”中。
        • 一个潜在的缺点是,在某些平台上,g++ 会自动将任何系统头文件包装在extern "C" 中,如果您在#include -isystem 路径中使用 C++ 头文件,则会导致有关 C 链接的奇怪错误.
        • +1 帮助我解决了烦人的 boost 警告问题stackoverflow.com/questions/35704753/warnings-from-boost
        • 为什么这比 1.5 小时前 OP 自己的回答说的完全相同?
        • 对于 Xcode:如果我的目标构建设置中的“其他 C++ 标志”中没有文件夹路径怎么办?有人可以详细说明这个解决方案吗?
        【解决方案8】:

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

        您也可以通过command line 进行操作。

        另一个 GCC 页面专门针对 disabling warnings

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

        GCC 通过classifying 警告类型来解决这个问题。您可以将它们分类为警告或忽略。之前链接的文章将向您展示哪些警告可能被禁用。

        注意:您也可以使用attributes 按摩源代码以防止某些警告;但是,这会将您与 GCC 紧密地联系在一起。

        注意2:GCC 也使用微软编译器中使用的pop/push interface——微软通过这个接口禁用警告。我建议您对此进行进一步调查,因为我不知道这是否可能。

        【讨论】:

        • 我考虑了编译指示,但如果我在包含标题之前取消警告,如何在#include 之后将其设置回先前状态?我想查看项目代码的所有警告(已经帮助了我几次),但可以从命令行进行控制。
        【解决方案9】:

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

        【讨论】:

        • +1 提供好的建议:D,但他在问如何做一些具体的事情:D
        • 有些警告是不可能或很难修复的,尤其是在第 3 方代码中,尤其是在像 Boost 这样的元编程丰富的代码中。
        • 困扰我的更糟糕的是 “'c' 的声明遮蔽了 'this' [-Werror=shadow] 的成员” 深,深在一些 boost 标头中.这当然不是问题,但它和类似的问题正在喷涌而出,让我很难在我们的代码库中找到真正的影子。
        【解决方案10】:

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

        【讨论】:

        • 这实际上可能是个好主意。第三方包含不会每天都在变化。
        • 没错。尽管我在 Linux 中使用它们的次数不多,但它们在 Visual Studio 上运行良好。
        • 不,它们仍然会出现在编译中,除非您使用其他方式来抑制它们(例如-isystem,但请记住在编译标头和代码中都使用它)
        猜你喜欢
        • 2012-10-02
        • 2019-11-04
        • 2021-09-04
        • 2011-03-25
        • 1970-01-01
        • 2021-12-23
        • 2015-08-01
        • 2015-10-16
        相关资源
        最近更新 更多