为 C++ 标准库配置 clang-check

Configure clang-check for c++ standard libraries

我正在尝试 运行 Ale 作为我的 linter,它又使用 clang-check 来检查我的代码。

$ clang-check FeatureManager.h
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "FeatureManager.h"
No compilation database found in /home/babbleshack/ or any parent directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
/home/babbleshack/FeatureManager.h:6:10: fatal error: 'unordered_map' file not found
#include <unordered_map>
         ^~~~~~~~~~~~~~~
1 error generated.
Error while processing /home/babbleshack/FeatureManager.h.

而使用 clang++ returns 编译只是一个警告。

$ clang++ -std=c++11 -Wall FeatureManager.cxx FeatureManager.h
clang-5.0: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]

没有允许我设置编译标志的 clang-check 标志。

花了一些时间才弄明白,但你可以做到

clang-check file.cxx -- -Wall -std=c++11 -x c++

或者如果您使用的是 clang-tidy

clang-tidy file.cxx -- -Wall -std=c++11 -x c++

为了同时使用 ALE,我将以下内容添加到我的 vimrc

let g:ale_cpp_clangtidy_options = '-Wall -std=c++11 -x c++' let g:ale_cpp_clangcheck_options = '-- -Wall -std=c++11 -x c++'

如果您希望 ALE 也适用于 C,则必须对 g:ale_c_clangtidy_optionsg:ale_c_clangcheck_options 执行相同的操作。

我被类似的错误消息困扰了太久:

/my/project/src/util.h:4:10: error: 'string' file not found [clang-diagnostic-error]
#include <string>
         ^

我看到其他 questions 提示我缺少一些关键包,但似乎所有东西都已经安装好了(而且我的代码 built 很好,只是clang-tidy 越来越不高兴了)。

传递 -v 表明我的 .h 文件的处理方式不同:

$ clang-tidy ... src/*.{h,cc} -- ... -v
...
clang-tool ... -main-file-name util.cc ... -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9 ... -x c++ ... /tmp/copy/src/util_test.cc
...
clang-tool ... -main-file-name util.h ... -x c-header /my/project/src/util.h
...

正如 Kris 指出的那样,关键区别在于 -x c-header 标志,这是因为 clang assumes a .h file contains C, not C++,这反过来意味着系统 C++ 包含未用于处理 util.h.

但是 -main-file-name 标志对我来说也很奇怪;为什么头文件会成为主文件?在四处挖掘时,我还发现 this short but insightful answer 头文件不应该首先直接编译!使用 src/*.cc 而不是 src/*.{h,cc} 通过从不要求 Clang 首先尝试自己处理 .h 来完全避免问题!

不过,这确实带来了更多麻烦。默认情况下不会报告这些头文件中的错误,因为它们不是您要求 clang-tidy 查看的文件。这是“Use -header-filter=. to display errors from all non-system headers.*”消息 clang-tidy 打印出来的地方。如果我通过 -header-filter=src/.*(只包含我的 src 头文件,而不包含我随 -I 一起包含的任何其他头文件)我在我的头文件中看到了预期的错误。呸!

我不确定总体上是更喜欢 -x c++ 还是 -header-filter=.*-header-filter 的缺点是您必须调整过滤器正则表达式,而不是仅仅传递要检查的文件。但另一方面,孤立地处理头文件本质上是浪费工作(我希望在更大的项目中会很快加起来)。