如何禁用没有命令行开关的gcc警告?

12

我收到了以下警告:

warning: 'X' is initialized and declared 'extern'

而且它 看起来不是什么大问题,我可以禁用它。在我的情况下更改代码并不是一个好主意,因为我无法控制代码,我只需要编译它。所以我想要禁用这个警告。

如果它旁边有一个-WSomeDefect键,那么我可以使用-Wno-SomeDefect命令行开关,但看起来没有明显的开关可以关闭此警告。

我如何禁用这样的警告?


6
如果您无法控制代码,那么它是一个库吗?在这种情况下,您应该使用“-isystem”(对于GCC和clang)来包含它,而不是使用“-I”,以禁用其中的所有警告。我也不同意这个警告“不是什么大问题”:它可能是无害的,但与答案所说的不同,我认为它通常指出了代码中的错误,并暗示作者不理解“extern”说明符的语义。因此,这是一个有效的警告,应该引起重视。 - Konrad Rudolph
4
因为这样你就不能使用-Werror了。而你应该使用-Werror - Konrad Rudolph
1
你可以使用“-w”禁用所有警告,然后就可以结束了。 - cremno
1
@MarekR 这个警告有数百个实例,它们会淹没编译器输出。很难忽略。 - sharptooth
1
@KonradRudolph: -isystem 绝不能被用作禁用警告的hack。CMake默认使用它,这是一个巨大的bug - 它与默认包含路径排序的交互方式不同于 -I,会导致问题破裂。-isystem 的主要/唯一用途是与 -nostdinc 一起使用,以使用不同的系统头文件集(例如您正在测试的未安装的libc版本),而不是基于其副作用的hack。 - R.. GitHub STOP HELPING ICE
显示剩余10条评论
4个回答

5
针对提出的问题,从GCC的源代码中可以看到,没有(半)具体的开关来禁用此警告。似乎只有通过禁用所有警告(-w)或通过-isystem将有问题的代码包含为系统头文件的方式来禁用它,但这两种方法都是非具体的抑制警告的方式。在GCC上有一个相关的已公开bug报告here和一个针对类似情况的无开关警告的已公开的元bughere
如果您不想使用这两种非具体化的抑制机制,那么您可能需要在GCC中打补丁或等待修复这些特定警告的错误。

3
有数百个此警告的实例,它们会淹没编译器输出,难以忽略。
如果这是外部库,有一种方法可以将此警告减少到单个警告报告中。我怀疑你可以接受单个警告消息。
使用自己的函数/方法包装此库API。您可以使用不同的命名空间来命名它们,以避免在使用此API的代码中进行复杂修改。这样,仅在包含有问题的头文件的源被包含时,才会报告此警告。目标是仅包括有问题的头文件一次。
根据这个API的具体情况,可能更难实现。
无论如何,如果这是第三方库,那么这种方法将使模拟该库并为您的代码编写测试更加容易。

2
产生此警告的代码不是有效的C,应该进行修复。C语言要求对约束违规(例如此类)发出“诊断”(警告或错误),并且不强制存在任何禁用它们的方法。我认为(并且我怀疑许多其他人也这样认为),extern是带有初始化程序的约束违规,因为在正常用法中,extern只提供声明而不是定义。然而,根据6.9.2 ¶1:

如果具有文件作用域和初始化程序的对象的标识符的声明,则该声明是标识符的外部定义。

由于语法似乎允许使用带有初始化程序的extern,因此这确实是一个有效的定义。

GCC有一个-w选项,可能会关闭警告,但代价是禁用所有警告,并且无法覆盖并重新启用其中一些警告。如果这是一个约束违规,并且需要修复无效代码,则这将是有意义的;但是,该代码是有效的,GCC绝对应该提供一种机制来避免产生关于它的虚假警告。

如Eljay在评论中指出:

警告分为几类:标准所需的诊断消息;常见意外语言滥用/误用的类似于lint的静态分析;出于良好意图但仍具有风格上的观点(例如-Weffc ++);可能过于迂腐和/或琐碎(例如-Weverything-pedantic)。后者的类别应该有“退出”方式来禁用特定的警告,例如在OP的情况下。

GCC通常会尽力遵守这个“应该”,大多数时候,我认为没有办法禁用此警告值得报告给GCC bug tracker


1
非常好的答案!警告分为几类:符合标准所需的诊断信息;对常见意外语言滥用/误用进行的类似lint的静态分析;出于善意但仍具有风格观点(例如,-Weffc ++);可能过于迂腐和/或琐碎(例如,-Weverything-pedantic)。后者应该有“选择退出”的方法来禁用特定的警告,就像在OP的情况下一样。 - Eljay
@Eljay:谢谢。在答案中添加了一条额外的注释。 - R.. GitHub STOP HELPING ICE

2
没有特定的标记可以禁用这个功能,这很不幸,但有一个-w标记可以禁用所有警告信息,无法重新启用。
GCC文档中得知:

-w
阻止所有警告信息的输出。

但更好的选择是从变量声明/定义中删除extern。这样编译器就知道变量在翻译单元内已经被定义。您可以联系代码的所有者以查看是否可以更改它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接