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

How do I disable a gcc warning which has no command line switch?

我收到以下警告:

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

looks like it's no big deal 我可以禁用它。更改代码对我来说并不是一个好主意,因为我无法控制代码,我只需要编译它。所以我想禁用警告。

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

如何禁用此类警告?

产生此警告的代码是无效的 C,应予以修复。C 语言需要发出 "diagnostics"(警告或错误)约束违规例如这个,并且不要求存在任何禁用它们的方法。我相信(而且我怀疑很多其他人也相信)extern 是对初始化器的约束违反,因为在正常使用中 extern 只提供声明,而不是定义。但是,根据 6.9.2 ¶1:

If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.

由于语法似乎允许 extern 带有初始值设定项,这确实是一个有效的定义。

GCC 有一个 -w 选项,它可能会关闭警告,但代价是禁用所有警告,无法覆盖和重新打开一些警告。如果这是违反约束的情况,这将是有意义的,并且将是修复无效代码的标志;然而,该代码是有效的,GCC 绝对应该提供一种机制,不会产生关于它的虚假警告。

正如 Eljay 在评论中指出的那样:

Warnings come in several categories: by the standard required diagnostic message; lint-like static analysis of common accidental language abuse/misuse; well-meaning but still stylistic opinion (e.g., -Weffc++); possibly too pedantic and/or minutia (e.g. -Weverything or -pedantic). The latter categories ought to have "opt-out" ways to disable the specific warning, such as in the OP's case.

GCC 通常会在大多数时候尝试遵守这一点应该,我认为如果没有办法禁用这一点,值得向 GCC bug tracker.

There're hundreds of instances of this warning and they flood the compiler output. Hard to ignore.

如果这是外部库,则可以将此警告减少为单个交战报告。 我怀疑您可以接受一条警告消息。

用你自己的 functions/methods 包装这个库 API。您可以使用不同的命名空间将它们命名为 1:1,以避免在使用此 API 的地方对自己的代码进行复杂的修改。这样只有在包含有问题的头文件的源时才会报告此警告。目的是只包含一次有问题的头文件。

这 API 看起来可能更难做到。

无论如何,如果这是第三方库,那么这种方法将使模拟该库和为您的代码编写测试变得更加容易。

直接回答所提出的问题:

从 GCC 的源代码可以看出,没有(半)特定的开关来禁用此警告。它似乎只能通过禁用所有警告 (-w) 或通过 -isystem 将违规代码作为系统 header 包括在内来禁用,这两者都是 non-specific 在抑制警告中。

在 GCC here and an open meta-bug for similar cases of warnings without switches here 上有一个相关的公开错误报告。

如果您不想使用这两个 non-specific 抑制机制,那么您可能需要在 GCC 中添加一个额外的标志,或者等待修复错误以禁用此功能具体警告。

没有任何特定的标志来禁用它,这很不幸,但是有 -w 标志将禁用所有警告,无法重新启用它们。

来自GCC docs

-w
Inhibit all warning messages.

但这里更好的选择是从变量 declarations/definitions 中删除 extern。这样,编译器就知道变量是在翻译单元中定义的。您可以联系代码的所有者,看看他们是否可以更改它。