仍然是内联的,因为编译器会自动内联

  • 本文关键字:编译器 仍然是 因为 c++ gcc
  • 更新时间 :
  • 英文 :


下面是代码a1.cpp

#include <stdio.h>
void func(void)
{
printf("hello worldn");
}
int main()
{
func();
return 0;
}

代码a2.cpp

#include <stdio.h>
inline void func(void)
{
printf("hello worldn");
}
int main()
{
func();
return 0;
}

它们只与关键字'inline'不同

然后将它们编译成assemble

g++ -S a1.cpp
g++ -S a2.cpp

的结果是:inline不起作用。函数调用仍然在main.

然后我用优化器

编译它们
g++ -O2 -S a1.cpp
g++ -O2 -S a2.cpp

的结果是:inline适用于a2。S,但是a1。S也替换了函数调用。内联似乎是自动添加的。

所以当内联在编码时是必需的。

inline关键字所做的就是允许在多个翻译单元中定义一个变量或函数,只要所有的定义都是相同的,就不会违反"一个定义规则"。它有绝对没有内联调用到函数。它所做的是允许一个函数(或变量,自c++ 17起)定义内联在头文件中,包含在多个翻译单元中,而不是必须在头文件中声明函数,并在一个翻译单元中外部定义它。

考虑以下程序:

header.hpp

#include <iostream>
void foo() {
std::cout << "hello worldn";
}

a.cpp

#include "header.hpp"

b.cpp

#include "header.hpp"
int main() {}

这个程序违反了一个定义规则,因为foo在两个翻译单元中定义。因此,它是病态的,不需要诊断。将inline关键字添加到foo中,该程序将变得正确且定义良好。foo仍将在多个翻译单元中定义,但由于它是inline,并且这些定义是相同的,因此不会违反单一定义规则。


注意,像这样在头文件中定义函数可以帮助编译器内联调用函数(因为函数的定义在多个翻译单元的调用点是可见的)。但这并不是必须的。大多数现代编译器/链接器工具链实现了某种形式的链接时优化,可以内联调用在其他翻译单元中定义的函数。

所以当编码时内联是必要的

简短的回答:可能从来没有(也从来没有)。

长答案:取决于你对"必要"的定义。如果有必要将某些函数调用扩展为内联的,并且有必要从多个翻译单元调用该函数,并且由于任何原因该函数不能具有内部链接,并且您必须使用不支持链接时间优化的旧编译器,或者由于其他原因无法启用该优化,那么也许您有必要定义内联函数的情况。这样的情况可能相当罕见。

请注意,由于在这种假设的情况下,调用必须内联展开,因此您必须还需要一些其他技术来强制内联展开。没有标准的方法存在,但有语言扩展。

虽然内联定义可能不是必需的,但使用它们主要是因为它们方便和简单,特别是在变量的情况下。


请注意,关于内联函数有两个常见的(并且相互矛盾的)误解:

  • 表示函数只展开对内联函数的调用和/或不展开对非内联函数的调用。你已经证明这种误解是错误的。
  • 定义内联函数与函数调用是否可以内联展开无关。它确实与此有关:只有当函数在相同的翻译单元中定义时,编译器才能内联地展开函数调用(此限制不适用于链接器)。由于非内联函数只能在一个TU中定义,因此对它的调用也只能在一个TU中内联(由编译器)。此外,编译器确实使用内联声明作为启发式方法来确定是否内联展开调用。即使在今天。至少基于源代码;从技术上讲,它可能是永远不会被调用的死代码。

相关内容

最新更新