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

Tho*_*mas 4 c c++ clang

这个问题略有关系,但不一样。

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

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

生成/foo.h

inline void foo(int unused) {  // warning: unused parameter 'unused'
}
Run Code Online (Sandbox Code Playgroud)

生成/foo.cc

#include "foo.h"

// There is actual code here, but it doesn't matter.
Run Code Online (Sandbox Code Playgroud)

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

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

主文件

#include "foo.h"

int main() {
  foo(42);
}
Run Code Online (Sandbox Code Playgroud)

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

$ g++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc
Run Code Online (Sandbox Code Playgroud)

但是,使用 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.
Run Code Online (Sandbox Code Playgroud)

添加--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.
Run Code Online (Sandbox Code Playgroud)

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

这实际上几乎记录在案:

#include指找到相对于当前目录中的文件指令视为包括一个系统标题,如果包括文件被作为系统标题处理。

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

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

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

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

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

Tho*_*mas 6

我低估了 CMake;这可以在不增加很多混乱的情况下工作:

set_source_files_properties(generated/foo.cc PROPERTIES COMPILE_FLAGS -w)
Run Code Online (Sandbox Code Playgroud)