废除C++中的包含文件

ana*_*lyg 23 c++ coding-style include

假设我在C++源文件中有以下代码(字面意思):

// #include <iostream> // superfluous, commented-out
using std::cout;
using std::endl;

int main()
{
    cout << "Hello World" << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

即使#include <iostream>被注释掉,我也可以编译这段代码:

g++ -include my_cpp_std_lib_hack source.cpp
Run Code Online (Sandbox Code Playgroud)

my_cpp_std_lib_hack是某个中心位置的文件,其中包含C++标准库的所有文件:

#include <ciso646>
#include <climits>
#include <clocale>
...
#include <valarray>
#include <vector>
Run Code Online (Sandbox Code Playgroud)

当然,我可以为我关心的所有编译器(即MS Visual Studio和其他一些编译器)使用适当的编译选项,并且我还使用预编译的头文件.

使用这样的hack给了我以下优点:

  • 快速编译(因为所有标准库都是预编译的)
  • #include当我想要的是添加一些调试输出时,无需添加s
  • 无需记住或查找std::max声明的所有时间
  • 感觉STL神奇地内置于语言中

所以我想知道:我在这里做错了吗?

在编写大型项目时,这个黑客会破坏吗?

也许其他人都已经使用过这个,没有人告诉过我?

Bil*_*eal 23

所以我想知道:我在这里做错了吗?

是.当然,你的标题是预编译的,但编译器仍然必须对整个包含的大量内容进行名称查找,这会减慢编译速度.

在编写大型项目时,这个黑客会破坏吗?

是的,这几乎就是问题所在.另外,如果其他人查看该代码,他们会想知道哪里std::cout(好吧,假设是用户定义的类型)来自.如果没有#include他们,他们将不知道任何事情.

更不用说,现在你必须链接大量的标准库功能,你可能已经(可能会有)首先避免链接.

如果你想使用很好的预编译,但即使禁用预编译,某人也应该能够构建每个实现文件.


Kri*_*son 15

唯一"错误"是您依赖于特定于编译器的命令行标志来使文件可编译.如果不使用GCC,您需要做一些不同的事情.大多数编译器可能确实提供了相同的功能,但最好编写可移植的源代码,而不是不必要地依赖于特定构建环境的功能.

其他程序员不应该琢磨你的Makefile(或Ant文件,或Eclipse工作区,或其他任何东西)来弄清楚事情是如何工作的.

这也可能会给IDE的用户带来问题.如果IDE不知道包含哪些文件,则可能无法提供自动完成,源浏览,重构和其他此类功能.

(FWIW,我认为最好有一个包含您在项目中使用的所有标准库头文件的头文件.它使预编译更容易,使得更容易移植到非标准环境,以及还有助于处理当标题包含在不同源文件中的不同顺序时有时会出现的问题.但是每个源文件应该明确包含该头文件;应该没有魔法.)