为什么简单的 C++ 源文件的预处理文件包含数千行代码?
Why preprocessed file of simple C++ source file contains thousands lines of code?
我正在学习 C++。我了解了一些 C++ 编译过程,编译过程的第一步是预处理。我很好奇预处理后源文件会发生什么,所以我用 C++ 编写了几行代码。这是我的代码:
#include <iostream>
using std::cout;
using std::endl;
#define PI 3.1416
int main()
{
cout << "Hello World\n";
cout << "The value of PI is: " << PI << '\n';
}
不超过十行代码。
我使用这个编译器标志 g++ -E main.cpp > main.p
所以预处理文件是 main.p
。
预处理文件main.p
包含28634行代码。
main.p
的前 15 行看起来像:
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.cpp"
# 1 "/usr/include/c++/9/iostream" 1 3
# 36 "/usr/include/c++/9/iostream" 3
# 37 "/usr/include/c++/9/iostream" 3
# 1 "/usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h" 1 3
# 252 "/usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h" 3
# 252 "/usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h" 3
main.p
的最后 10 行看起来像:
using std::cout;
using std::endl;
int main()
{
cout << "Hello World\n";
cout << "The value of PI is: " << 3.1416 << '\n';
}
为什么main.p
包含这么多行代码?我的假设(如果我错了请纠正我)是用于构建 iostream
库的所有代码都包含在 main.p
文件中,如果是这样则不是 main.cpp
的二进制文件或可执行文件不必要的大?
#include
指令直接将包含文件的内容粘贴到最终文件中进行编译。对于 C++,单个包含可以从包含的文件中拖出许多其他包含,使生成的文件膨胀。
这正是 C++ 包含工作的方式。可执行文件大小将包含支持您的功能所需的代码,没有办法绕过它。
您的假设是正确的:iostream
header 的全部内容都包含在预处理器输出中。这会传递地发生:iostream
包含的每个 header 也包含在内,依此类推。这基本上就是 #include
的意思!
但是,这并不意味着您的可执行文件会很大:
- Headers 通常只包含声明,不包含实现。声明不包含任何可执行代码。实际实现在共享库中。
- 标准库中的许多 header 仅包含模板,这些模板在实例化之前不会发出任何代码。
- 内联实现 允许在 header 中,但它们在调用站点中内联,因此只要您不调用它们,它们就不会要么被编译。
我正在学习 C++。我了解了一些 C++ 编译过程,编译过程的第一步是预处理。我很好奇预处理后源文件会发生什么,所以我用 C++ 编写了几行代码。这是我的代码:
#include <iostream>
using std::cout;
using std::endl;
#define PI 3.1416
int main()
{
cout << "Hello World\n";
cout << "The value of PI is: " << PI << '\n';
}
不超过十行代码。
我使用这个编译器标志 g++ -E main.cpp > main.p
所以预处理文件是 main.p
。
预处理文件main.p
包含28634行代码。
main.p
的前 15 行看起来像:
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.cpp"
# 1 "/usr/include/c++/9/iostream" 1 3
# 36 "/usr/include/c++/9/iostream" 3
# 37 "/usr/include/c++/9/iostream" 3
# 1 "/usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h" 1 3
# 252 "/usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h" 3
# 252 "/usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h" 3
main.p
的最后 10 行看起来像:
using std::cout;
using std::endl;
int main()
{
cout << "Hello World\n";
cout << "The value of PI is: " << 3.1416 << '\n';
}
为什么main.p
包含这么多行代码?我的假设(如果我错了请纠正我)是用于构建 iostream
库的所有代码都包含在 main.p
文件中,如果是这样则不是 main.cpp
的二进制文件或可执行文件不必要的大?
#include
指令直接将包含文件的内容粘贴到最终文件中进行编译。对于 C++,单个包含可以从包含的文件中拖出许多其他包含,使生成的文件膨胀。
这正是 C++ 包含工作的方式。可执行文件大小将包含支持您的功能所需的代码,没有办法绕过它。
您的假设是正确的:iostream
header 的全部内容都包含在预处理器输出中。这会传递地发生:iostream
包含的每个 header 也包含在内,依此类推。这基本上就是 #include
的意思!
但是,这并不意味着您的可执行文件会很大:
- Headers 通常只包含声明,不包含实现。声明不包含任何可执行代码。实际实现在共享库中。
- 标准库中的许多 header 仅包含模板,这些模板在实例化之前不会发出任何代码。
- 内联实现 允许在 header 中,但它们在调用站点中内联,因此只要您不调用它们,它们就不会要么被编译。