跨多个 C++ 翻译单元的内联函数

pol*_*pol 2 c++ inline

我最近学习了 C++ 中的内联函数。我了解它们是如何工作的(在扩展代码而不是进行跳转等方面),但是当涉及到多个翻译单元 / *.cpp 文件时,我对如何使用它们感到有些困惑。

我已经读过,根据经验,我应该在头文件中包含函数本身的定义(而不仅仅是它的声明),然后在我打算使用所述内联函数的每个翻译单元中包含头文件。这对于内联函数来说不是问题,因为它只会在每个翻译中独立存在,并在需要时/如果需要(由编译器决定)进行扩展[如果我对任何一个错误,请纠正我!]

但是,我也读到在链接期间,即使头文件中不存在内联函数本身的定义,链接器也可以找到它的定义并在需要时扩展它。但是链接器如何能够从不同的翻译单元扩展一个函数呢?如果是这样,为什么我需要在每个翻译单元中包含函数的定义(通过头文件)?

t.n*_*ese 5

inline函数前面的关键字只是编译器首选内联的可选指示符。现代编译器inline在代码内联时并不关心关键字。

关于重要的含义inline是“允许多个定义”,如果成员函数定义在类的主体中,则隐式内联。

inline如果您在多个翻译单元中具有相同的函数定义,则需要(例如,如果您将函数定义放在一个标题中,并且该标题包含在多个 cpp 文件中)

我已经读过,根据经验,我应该在头文件中包含函数本身的定义(而不仅仅是它的声明),然后在我打算使用所述内联函数的每个翻译单元中包含头文件。这对于内联函数来说不是问题,因为它只会在每个翻译中独立存在,并在需要时/如果需要(由编译器决定)扩展自身

将函数定义放在头文件中使工具链更容易进行内联,因为它在使用时知道其定义并且可以在编译步骤中执行内联。在多个翻译单元中有一个函数定义需要用inline.

但是,我也读到在链接期间,即使头文件中不存在内联函数本身的定义,链接器也可以找到它的定义并在需要时扩展它。但是链接器如何能够从不同的翻译单元扩展一个函数呢?

工具链可以对链接时(静态链接)的定义已知的任何函数(无论它们的定义在编译时是否已知)进行链接时优化(如内联),但链接时优化倾向于 - 在至少在过去 - 不如编译时优化有效。

链接时优化的问题是,工具链要么需要跟踪源代码提供的有助于优化的附加信息,要么需要依赖可能不太强大的策略,您可以在二进制文件上应用。

如果你有一个main.cpp看起来像这样的:

int sum(int a, int b) {
  return a+b;
}

int main() {
  std::cout << sum(3,4) << std::endl;
  return 0;
}

Run Code Online (Sandbox Code Playgroud)

任何现代编译器都会内联该代码(或者在这种情况下,事件将其完全优化为std::cout << 7 << std::endl;)。

这也将是好的和内联/优化:

总和

int sum(int a, int b) { // no inline keyword in front of the function
  return a+b;
}
Run Code Online (Sandbox Code Playgroud)

主程序

#include "sum.h"
int main() {
  std::cout << sum(3,4) << std::endl;
  return 0;
}

Run Code Online (Sandbox Code Playgroud)

但是一旦您#include "sum.h"在多个 cpp 文件中使用并将这些翻译单元链接在一起,您就会遇到问题并且需要使用inline. inline现在,在函数前面实际上只是告诉链接器在多个翻译单元中具有相同的定义是您的意图。

  • @pol`当我在标头中将函数声明为内联函数时,这是否会决定它是否会在每个函数调用上扩展?`是的,这完全取决于编译器,它可能会也可能不会内联函数,无论是否有在它之前是一个“内联”。是否这样做取决于编译器认为哪个更好。 (2认同)