当我在C ++程序中包含头文件中的某些函数时,整个头文件代码是否被复制到最终的可执行文件中,或者只生成特定函数的机器代码。例如,如果我从C ++中的std::sort
标头调用<algorithm>
,那么机器代码是仅针对sort()函数或整个<algorithm>
头文件生成的。
我认为Stack Overflow上存在一个类似的问题,但我已经尽力找到它(我曾经看了一次,但丢失了链接)。如果你能指出我的话,那就太棒了。
答案 0 :(得分:11)
你在这里混合了两个不同的问题:
这些只是由预处理器逐字复制到include
的位置。 algorithm
时,.cpp
的所有代码都会复制到#include <algorithm>
文件中。
大多数现代链接器都不会链接到您的应用程序中未调用的函数。即编写一个函数foo
并且永远不会调用它 - 它的代码不会进入可执行文件。因此,如果您#include <algorithm>
并且仅使用sort
,则会发生以下情况:
algorithm
文件推送到源文件sort
sort
的源(以及它调用的函数,如果有的话)添加到可执行文件中。其他算法的代码没有添加也就是说,C ++模板使问题进一步复杂化。这里需要解释一个复杂的问题,但简而言之 - 编译器会为您实际使用的所有类型扩展模板。因此,如果vector
int
和vector
string
,编译器将为代码中的vector
类生成两个代码的副本。由于您正在使用它(否则编译器不会生成它),链接器也会将其放入可执行文件中。
答案 1 :(得分:3)
实际上,整个文件被复制到.cpp文件中,它依赖于编译器/链接器,如果它只选择“需要”的功能,或者所有这些功能。
一般来说,简化摘要:
另外,它取决于属性 - &gt;声明用于导出的函数将永远不会被剥离。 另一方面,模板函数变体在使用时会“生成”,因此只编译您明确使用的变体。
编辑:未生成头文件代码,但在大多数情况下是手写的。
答案 2 :(得分:1)
如果您在源代码中#include
一个头文件,就好像该头文件中的文本是用#include
预处理器指令代替的。
通常标头包含声明,即有关库内部内容的信息。这样编译器允许您调用代码存在于当前编译单元之外的事物(例如,包含头部的.cpp文件)。当程序链接到可以运行的可执行文件时,链接器通常根据程序实际使用的内容决定要包含的内容。库也可以动态链接,这意味着可执行文件实际上不包含库代码,但库在运行时链接。
答案 3 :(得分:0)
这取决于编译器。今天大多数编译器都进行流量分析以修剪掉未调用的函数。 http://en.wikipedia.org/wiki/Data-flow_analysis