C++ 为什么尽管使用了-isystem,clang仍在我的头上报告警告,而gcc却不报告警告?
略相关但不相同 在ArchLinux上使用Clang7.0.1。我喜欢干净的代码,所以我想启用所有警告并将它们视为错误 问题是,我的构建中有一些自动生成的文件没有警告,例如: 生成/foo.hC++ 为什么尽管使用了-isystem,clang仍在我的头上报告警告,而gcc却不报告警告?,c++,c,clang,C++,C,Clang,略相关但不相同 在ArchLinux上使用Clang7.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.
inline void foo(int unused) { // warning: unused parameter 'unused'
}
生成/foo.cc
#include "foo.h"
// There is actual code here, but it doesn't matter.
#include "foo.h"
int main() {
foo(42);
}
由于这些文件是由第三方工具生成的,我无法轻松修改它们,因此我使用-isystem
来抑制生成的
目录中的所有警告
我还有一个主文件,它取决于生成的文件:
main.cc
#include "foo.h"
// There is actual code here, but it doesn't matter.
#include "foo.h"
int main() {
foo(42);
}
使用gcc,即使启用了所有警告,我也可以很好地编译它
$ g++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc
但是,使用clang时,它无法编译生成的/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.
添加没有帮助:
$ 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
替换#include
。这几乎不是一个正确的修复方法,但它提供了一个线索:我怀疑clang在当前目录
中查找foo.h
,而不是扫描包含路径,当然
没有标记为系统包含目录
事实上,这几乎被记录在案:
如果include文件被视为系统头,则查找相对于当前目录的文件的#include
指令被视为包含系统头
但是,它没有说明如果包含的文件根本不是头会发生什么
我能想到的变通办法,没有一个是好的:
- 在编译生成的文件之前对其进行后处理。例如,通过添加
。丑陋,而且很难用一种非常便携的方式完成#pragma-clang-system_标题
- 在编译生成的
文件时,请修改生成系统CMake,以不启用警告。但这可能意味着我必须为它们添加一个单独的目标,这意味着要么复制大量的标志和配置,要么复制一个枯燥但更复杂的.cc
CMakeLists.txt
我宁愿设置正确的标志,就像gcc一样。这可能吗?我低估了CMake;这样做不会造成太多混乱:
set_source_files_properties(generated/foo.cc PROPERTIES COMPILE_FLAGS -w)
您不能使用
#pragma
指令从这些文件或包含它们的文件中禁用警告吗?这至少是我会采取的方法。是的,这意味着编译器特定的#ifdef
部分。@UlrichEckhardt生成的头包含在生成的源中,因此这需要进行后处理。好的,建议不要保留未使用的变量。您肯定应该为此启用警告。可移植解决方案:内联void foo(int unused){(void)unused;}
@Lundin它在机器生成的代码中。我没有代码生成器。是的,但它仍然是可疑代码,所以你不应该禁用警告。它工作正常。