为什么尽管使用了 -isystem,但 clang 在我的标头上报告警告,而 gcc 没有报告警告?

  • 本文关键字:报告 警告 gcc clang -isystem c++ c clang
  • 更新时间 :
  • 英文 :


与这个问题略有关系,但并不相同。

在 Arch Linux 上使用 clang 7.0.1。我喜欢干净的代码,所以我想启用所有警告并将它们视为错误。

问题是我的构建中有一些自动生成的文件并非没有警告,例如:

生成/foo.h

inline void foo(int unused) {  // warning: unused parameter 'unused'
}

生成/foo.cc

#include "foo.h"
// There is actual code here, but it doesn't matter.

由于这些文件是由第三方工具生成的,因此我无法轻松修改它们,因此我使用-isystem来抑制来自generated目录的所有警告。

我还有一个依赖于生成的主文件:

main.cc

#include "foo.h"
int main() {
foo(42);
}

使用 gcc,即使启用了所有警告,我也可以很好地编译它。

$ g++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc

但是,使用clang,它无法编译generated/foo.cc

$ clang++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc
In file included from generated/foo.cc:1:
generated/foo.h:1:21: error: unused parameter 'unused'
[-Werror,-Wunused-parameter]
inline void foo(int unused) {
^
1 error generated.

添加--system-header-prefix无济于事:

$ clang++ -Wall -Wextra -pedantic -Werror -isystem generated --system-header-prefix=generated/ -omain main.cc generated/foo.cc
In file included from generated/foo.cc:1:
generated/foo.h:1:21: error: unused parameter 'unused'
[-Werror,-Wunused-parameter]
inline void foo(int unused) {
^
1 error generated.

有用的是将#include "foo.h"替换为生成的("请勿修改")代码中的#include <foo.h>。这几乎不是一个正确的修复,但它提供了一个线索:我怀疑 clang 以某种方式在当前目录中查找foo.h.而不是扫描包含路径,当然.没有标记为系统包含目录。

这实际上几乎是有据可查的:

如果将包含文件视为系统头,则查找相对于当前目录的文件的#include指令将被视为包含系统头。

但是,它没有说明如果包含文件根本不是标头会发生什么。

我能想到的解决方法,没有一个是好的:

  • 在编译之前对生成的文件进行后处理。 例如,通过添加#pragma clang system_header.丑陋,而且以一种非常便携的方式很难做到。

  • 摆弄生成系统 CMake,以便在编译生成的.cc文件时不启用警告。但这可能意味着我必须为它们添加一个单独的目标,这意味着要么复制大量标志和配置,要么复制 DRY 但更复杂的CMakeLists.txt

我宁愿设置正确的标志,就像 gcc 一样。这可能吗?

我低估了CMake;这不会增加很多混乱:

set_source_files_properties(generated/foo.cc PROPERTIES COMPILE_FLAGS -w)

最新更新