c++头文件如何工作?

时间:2021-12-07 15:06:43

When I include some function from a header file in a C++ program, does the entire header file code get copied to the final executable or only the machine code for the specific function is generated. For example, if I call std::sort from the <algorithm> header in C++, is the machine code generated only for the sort() function or for the entire <algorithm> header file.

当我在c++程序中包含头文件中的一些函数时,是否会将整个头文件代码复制到最终可执行文件中,或者只生成特定函数的机器码。例如,如果我调用std::sort from header in c++,它是仅为sort()函数或整个 头文件生成的机器代码。

I think that a similar question exists somewhere on Stack Overflow, but I have tried my best to find it (I glanced over it once, but lost the link). If you can point me to that, it would be wonderful.

我认为在Stack Overflow上有一个类似的问题,但是我已经尽力找到它了(我浏览了它一次,但是丢失了链接)。如果你能给我指出来,那就太好了。

4 个解决方案

#1


10  

You're mixing two distinct issues here:

这里有两个不同的问题:

  1. Header files, handled by the preprocessor
  2. 头文件,由预处理程序处理
  3. Selective linking of code by the C++ linker
  4. 由c++链接器选择代码链接

Header files

These are simply copied verbatim by the preprocessor into the place that includes them. All the code of algorithm is copied into the .cpp file when you #include <algorithm>.

它们只是由预处理器逐字复制到包含它们的位置。当#include 时,所有算法代码都被复制到.cpp文件中。

Selective linking

Most modern linkers won't link in functions that aren't getting called in your application. I.e. write a function foo and never call it - its code won't get into the executable. So if you #include <algorithm> and only use sort here's what happens:

大多数现代链接器不会在应用程序中不被调用的函数中链接。例如,编写一个函数foo,不要调用它——它的代码不会进入可执行文件。如果你#include <算法> 并且只使用sort这里会发生:

  • The preprocessor shoves the whole algorithm file into your source file
  • 预处理程序将整个算法文件塞到源文件中
  • You call only sort
  • 你只叫
  • The linked analyzes this and only adds the source of sort (and functions it calls, if any) to the executable. The other algorithms' code isn't getting added
  • 链接分析了这一点,并且只将sort的源(以及它调用的函数,如果有的话)添加到可执行文件中。其他算法的代码没有被添加

That said, C++ templates complicate the matter a bit further. It's a complex issue to explain here, but in a nutshell - templates get expanded by the compiler for all the types that you're actually using. So if have a vector of int and a vector of string, the compiler will generate two copies of the whole code for the vector class in your code. Since you are using it (otherwise the compiler wouldn't generate it), the linker also places it into the executable.

也就是说,c++模板使问题更加复杂。这里要解释的是一个复杂的问题,但简而言之——编译器会为您实际使用的所有类型扩展模板。如果有一个int向量和一个字符串向量,编译器会为你的代码生成两个向量类的整个代码拷贝。由于您正在使用它(否则编译器不会生成它),链接器也将它放置到可执行文件中。

#2


3  

In fact, the entire file is copied into .cpp file, and it depends on compiler/linker, if it picks up only 'needed' functions, or all of them.

实际上,整个文件被复制到.cpp文件中,如果它只获取“需要的”函数或所有的函数,那么它取决于编译器/链接器。

In general, simplified summary:

一般来说,简单总结:

  • debug configuration means compiling in all of non-template functions,
  • 调试配置意味着编译所有非模板函数,
  • release configuration strips all unneeded functions.
  • 释放配置删除所有不需要的功能。

Plus it depends on attributes -> function declared for export will be never stripped. On the other side, template function variants are 'generated' when used, so only the ones you explicitly use are compiled in.

此外,它还取决于属性——声明用于导出的>函数将不会被删除。另一方面,模板函数变体在使用时是“生成的”,因此只有显式使用的模板函数变体被编译。

EDIT: header file code isn't generated, but in most cases hand-written.

编辑:头文件代码没有生成,但是在大多数情况下是手写的。

#3


1  

If you #include a header file in your source code, it acts as if the text in that header was written in place of the #include preprocessor directive.

如果您的源代码中包含一个头文件,它的作用就好像头文件中的文本被写入了#include预处理指令。

Generally headers contain declarations, i.e. information about what's inside a library. This way the compiler allows you to call things for which the code exists outside the current compilation unit (e.g. the .cpp file you are including the header from). When the program is linked into an executable that you can run, the linker decides what to include, usually based on what your program actually uses. Libraries may also be linked dynamically, meaning that the executable file does not actually include the library code but the library is linked at runtime.

标题通常包含声明,即关于库中内容的信息。通过这种方式,编译器允许您调用代码存在于当前编译单元之外的东西(例如,您所包含的.cpp文件)。当程序链接到可运行的可执行文件时,链接器会根据程序实际使用的内容来决定包含哪些内容。库也可以动态链接,这意味着可执行文件实际上不包含库代码,而是在运行时链接库。

#4


0  

It depends on the compiler. Most compilers today do flow analysis to prune out uncalled functions. http://en.wikipedia.org/wiki/Data-flow_analysis

这取决于编译器。现在大多数编译器都进行流分析,以删除未调用的函数。http://en.wikipedia.org/wiki/Data-flow_analysis

#1


10  

You're mixing two distinct issues here:

这里有两个不同的问题:

  1. Header files, handled by the preprocessor
  2. 头文件,由预处理程序处理
  3. Selective linking of code by the C++ linker
  4. 由c++链接器选择代码链接

Header files

These are simply copied verbatim by the preprocessor into the place that includes them. All the code of algorithm is copied into the .cpp file when you #include <algorithm>.

它们只是由预处理器逐字复制到包含它们的位置。当#include 时,所有算法代码都被复制到.cpp文件中。

Selective linking

Most modern linkers won't link in functions that aren't getting called in your application. I.e. write a function foo and never call it - its code won't get into the executable. So if you #include <algorithm> and only use sort here's what happens:

大多数现代链接器不会在应用程序中不被调用的函数中链接。例如,编写一个函数foo,不要调用它——它的代码不会进入可执行文件。如果你#include <算法> 并且只使用sort这里会发生:

  • The preprocessor shoves the whole algorithm file into your source file
  • 预处理程序将整个算法文件塞到源文件中
  • You call only sort
  • 你只叫
  • The linked analyzes this and only adds the source of sort (and functions it calls, if any) to the executable. The other algorithms' code isn't getting added
  • 链接分析了这一点,并且只将sort的源(以及它调用的函数,如果有的话)添加到可执行文件中。其他算法的代码没有被添加

That said, C++ templates complicate the matter a bit further. It's a complex issue to explain here, but in a nutshell - templates get expanded by the compiler for all the types that you're actually using. So if have a vector of int and a vector of string, the compiler will generate two copies of the whole code for the vector class in your code. Since you are using it (otherwise the compiler wouldn't generate it), the linker also places it into the executable.

也就是说,c++模板使问题更加复杂。这里要解释的是一个复杂的问题,但简而言之——编译器会为您实际使用的所有类型扩展模板。如果有一个int向量和一个字符串向量,编译器会为你的代码生成两个向量类的整个代码拷贝。由于您正在使用它(否则编译器不会生成它),链接器也将它放置到可执行文件中。

#2


3  

In fact, the entire file is copied into .cpp file, and it depends on compiler/linker, if it picks up only 'needed' functions, or all of them.

实际上,整个文件被复制到.cpp文件中,如果它只获取“需要的”函数或所有的函数,那么它取决于编译器/链接器。

In general, simplified summary:

一般来说,简单总结:

  • debug configuration means compiling in all of non-template functions,
  • 调试配置意味着编译所有非模板函数,
  • release configuration strips all unneeded functions.
  • 释放配置删除所有不需要的功能。

Plus it depends on attributes -> function declared for export will be never stripped. On the other side, template function variants are 'generated' when used, so only the ones you explicitly use are compiled in.

此外,它还取决于属性——声明用于导出的>函数将不会被删除。另一方面,模板函数变体在使用时是“生成的”,因此只有显式使用的模板函数变体被编译。

EDIT: header file code isn't generated, but in most cases hand-written.

编辑:头文件代码没有生成,但是在大多数情况下是手写的。

#3


1  

If you #include a header file in your source code, it acts as if the text in that header was written in place of the #include preprocessor directive.

如果您的源代码中包含一个头文件,它的作用就好像头文件中的文本被写入了#include预处理指令。

Generally headers contain declarations, i.e. information about what's inside a library. This way the compiler allows you to call things for which the code exists outside the current compilation unit (e.g. the .cpp file you are including the header from). When the program is linked into an executable that you can run, the linker decides what to include, usually based on what your program actually uses. Libraries may also be linked dynamically, meaning that the executable file does not actually include the library code but the library is linked at runtime.

标题通常包含声明,即关于库中内容的信息。通过这种方式,编译器允许您调用代码存在于当前编译单元之外的东西(例如,您所包含的.cpp文件)。当程序链接到可运行的可执行文件时,链接器会根据程序实际使用的内容来决定包含哪些内容。库也可以动态链接,这意味着可执行文件实际上不包含库代码,而是在运行时链接库。

#4


0  

It depends on the compiler. Most compilers today do flow analysis to prune out uncalled functions. http://en.wikipedia.org/wiki/Data-flow_analysis

这取决于编译器。现在大多数编译器都进行流分析,以删除未调用的函数。http://en.wikipedia.org/wiki/Data-flow_analysis