当方法体位于头文件中时强制内联

Is inline forced when method body is in header file?

本文关键字:文件 方法 于头      更新时间:2023-10-16

我知道inline关键字只是对编译器的一个提示,而不是强制的(除非在MSVC中使用__forceinline)。

在header中声明内联函数也是这样吗?编译器将把代码放在哪个编译单元?

inline不仅仅是对编译器的一个提示。

一个内联函数可以在多个翻译单元中定义,所有这些定义将具有相同的类型、地址和定义。

如果一个函数是在头文件中定义的,那么它必须声明为inline,否则当它被包含在多个翻译单元中时,它将违反一个定义规则。

内联函数是:

  1. 全局作用域的函数可以使用关键字inline内联声明。
  2. 完全在class/struct/union定义内定义的函数,无论它是成员函数还是非成员友元函数,都始终是内联的。
  3. 声明为constexpr的函数总是内联的。

(源)

在header中声明内联函数时也是[inline是提示]的情况吗?

是的。inline关键字总是提示编译器执行"内联"。

但是,请注意这只是一个提示。编译器可以自由地忽略它(很多编译器都是这样做的)。

编译器能够对内联函数执行内联的真正原因是整个定义是可用的。您将注意到static函数和实例化函数模板的内联。

编译器将把代码放在哪个编译单元?

在链接之前,内联函数将在定义它的任何编译单元中被完全定义。它将被完整地编译到每个目标文件中。

在链接过程中,链接器将决定使用哪个定义,并丢弃所有其他定义。

参见此问题及其答案

该代码将出现在所有包含该头文件的编译单元中。inline的要点是告诉链接器这个函数可以在多个目标文件中找到,并且链接器可以选择这些副本中的任何一个。

内联不是强制的。如果在类定义中定义方法,则该方法是隐式内联的。它就像在类定义之外定义它,只是隐含了内联。这与定义在哪个文件中无关。

当您请求内联的函数实际上没有内联时,由编译器决定将其放在何处。在早期,您可以在包含头文件的每个文件中获得非导出副本。现在,应用了一些策略,比如将它放在与第一个构造函数、第一个方法或虚函数表相同的位置。compiler-dependent。