每当我们编译一个 c++ 文件时,都会生成一个 obj 文件。我想知道 obj 文件的大小取决于哪些因素?
只是为了让我的问题更清楚,例如一个 c++ 文件包含一个类声明,这个类有 1 个整数变量作为数据成员,并且还有一些成员函数。如果我编译这个文件,那么将创建一些 X 大小的 obj 文件。现在假设我添加了更多的数据成员和成员函数,那么obj文件的大小会改变吗?
每当我们编译一个 c++ 文件时,都会生成一个 obj 文件。我想知道 obj 文件的大小取决于哪些因素?
只是为了让我的问题更清楚,例如一个 c++ 文件包含一个类声明,这个类有 1 个整数变量作为数据成员,并且还有一些成员函数。如果我编译这个文件,那么将创建一些 X 大小的 obj 文件。现在假设我添加了更多的数据成员和成员函数,那么obj文件的大小会改变吗?
这取决于一百万个不同的因素,并且完全取决于平台、编译器和设置。
目标文件必须包含具有外部链接的函数的所有函数体程序集,以及具有外部链接的所有全局变量。任何具有内部链接的内容可能会或可能不会保证在目标文件中单独条目,因为这些条目可能已被优化并直接集成到其调用站点中。这在很大程度上取决于优化设置。
GCC 还具有“链接时间优化”选项,它实质上将整个源代码的副本添加到目标文件并显着增加其大小。
调试符号还添加了很多额外的数据。
对于您的 C++ 特定问题:类定义本身在程序集中并不真正可见。非内联成员函数只是更多必须编译的函数,而数据成员只是被视为与原始数据成员相同 - 如果您声明该类型的实例,它们将在调用堆栈上,但它们不直接影响汇编代码...除非您使用常量初始化事物;当然,常量确实会进入代码。
目标文件包含(除其他外)源代码编译后但链接之前的机器代码。因此,目标文件的大小基本上取决于代码的复杂性。
大多数编译器为您提供了在编译期间添加调试符号以使调试更容易的选项,但会增加目标文件的大小。您可以使用选项添加调试符号,并使用GCC 中的-g
选项剥离它们。-s
Visual Studio 也有类似的东西。
它严重依赖编译器,但是。
目标文件将包含可执行代码、链接存根和元数据。元数据可以是任何依赖于编译器的东西,所以这是不可能的——任何事情都可能发生在它身上,这取决于编译器的想法。链接存根是为具有外部链接的所有实体以及对其他对象文件中的实体的所有传出引用创建的——这不会直接受到将成员添加到同一对象文件中的类中的影响。
现在开始编码。当你添加一个成员变量时,它必须被构造和销毁——这将需要一个构造函数和一个析构函数,这两者都可能是微不足道的。如果它们不是微不足道的,这将导致代码大小略有增长,因为现在必须做一些额外的事情来处理这些成员变量,这需要额外的代码。