是否有工具可以解析 C++ 项目并决定 头文件是否包含它们使用的内容: 即,如果文件 Foo.cc(或 Foo.h)提到某个 Bar 类(例如向量),那么 它本身包含一个头文件 定义类(定义 Bar 的文件,例如
<vector>
)?
编辑:我想澄清一下:如果头文件 Foo.h 提到向量及其包含之一 已经包含了向量,编译器很高兴。我不想那样。如果 Foo.h 提到向量 无论如何,它应该直接包含它而不依赖于另一个标头。编译器能捕捉到这个吗?
编译器会为你做这件事。许多 C++ 风格指南强烈建议,因此所有 .cpp 文件都应包含相应的标头作为第一个实质性包含指令。
我为此使用了一个脚本。这是一个简化版本:
#!/usr/bin/env bash
# hcheck: Check header file syntax (works on source files, too...)
if [ $# -eq 0 ]; then
echo "Usage: $0 <filename>"
exit 1
fi
for f in "$@" ; do
case $f in
*.c | *.cpp | *.cc | *.h | *.hh | *.hpp )
echo "#include \"$f\"" > hcheck.cpp
printf "\n\033[4mChecking $f\033[0m\n"
make -s hcheck.o
rm -f hcheck.o hcheck.cpp
;;
esac
done
当然,您需要有一个
Makefile
。如果您不希望这样,请将 make
行替换为适当的 gcc
命令(不要忘记任何标志!)。如果您的 Makefile
将对象放置在当前目录之外的其他位置,您还需要调整它。
我确信还有很多需要改进的地方。当我告诉人们这一点时,下意识的反应是“编译标头是一个愚蠢的想法”,但它对我来说效果很好,并且可以用于没有源代码或未首先包含在源代码中的标头。
减轻实现自给自足标头目标的负担的一种方法是确保在那里声明的任何类(通常)或自由函数(有时)都有非常具体的意图,例如遵守单一责任原则。通过这样做,需要包含标头的依赖项将会减少。
我不知道有这样的工具。这个问题并不像看起来那么容易解决。例如,以下应该包含哪些头文件才能自给自足?
#ifdef FOO
std::vector<int> getVector();
#endif
void doStuff(std::string);
可能需要,也可能不需要包括
<vector>
。这取决于是否定义了 FOO
,以及可能定义也可能不定义,取决于此文件之前包含的内容。
一般来说,预处理器宏确实会扰乱任何“孤立”读取标头的尝试。