内联仍然是必要的,因为编译器会自动内联
这是代码 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;
}
它们仅与关键字“内联”不同
然后我将它们编译成汇编
g++ -S a1.cpp
g++ -S a2.cpp
结果是:内联不起作用。函数调用保留在 main 中。
然后我用优化器编译它们
g++ -O2 -S a1.cpp
g++ -O2 -S a2.cpp
结果是:inline 在 a2.s 中有效,但 a1.s 也替换了函数调用。似乎内联是自动添加的。
所以在编码时需要内联。
回答
所有inline
关键字的作用是允许在多个翻译单位来定义一个变量或函数在不违反一个定义规则,只要所有的定义是相同的。它与对函数的内联调用完全无关。它的作用是允许在包含在多个翻译单元中的头文件中内联定义函数(或变量,因为 C++17),而不必在头文件中声明函数并在外部定义它在一个翻译中单元。
考虑以下程序:
头文件
#include <iostream>
void foo() {
std::cout << "hello worldn";
}
a.cpp
#include "header.hpp"
b.cpp
#include "header.hpp"
int main() {}
这个程序违反了一个定义规则,因为它foo
是在两个翻译单元中定义的。因此它的格式不正确,不需要诊断。添加inline
关键字 to foo
,该程序将变得正确且定义明确。 foo
仍将在多个翻译单元中定义,但由于它inline
和这些定义是相同的,因此不会违反一个定义规则。
请注意,在这样的标头中定义函数可能有助于编译器内联对函数的调用(因为函数的定义在多个翻译单元中的调用点可见)。但这绝不是必需的。大多数现代编译器/链接器工具链都实现了某种形式的链接时优化,可以内联对其他翻译单元中定义的函数的调用。