问题在标题中,但不一定很清楚,下面是我想要做的代码示例:
#include <iostream>
typedef void (*functions)(void);
inline void func_A()
{
std::cout << "I am A !" << std::endl;
}
inline void func_B()
{
std::cout << "I am B !" << std::endl;
}
int main()
{
functions funcs[2] = {func_A, func_B};
for (int i = 0; i < 2; i++)
funcs[i]();
return 0;
}与内联函数的兴趣相比,这是一个好主意吗?编译器能很好地处理这个问题吗?
提前谢谢!
发布于 2022-08-12 22:56:34
您可以轻松地查看编译器的输出,以了解它们如何处理代码。这里我使用O2优化标志的当前编译器的结果,请参阅https://godbolt.org/z/ecjjz88hs。
当前的MSVC似乎根本没有优化调用。它甚至没有展开循环,因此也无法确定哪些函数实际上被间接调用,因此也无法内联函数调用。
GCC 12.1确实展开了循环,并将间接函数调用转换为直接函数调用,但决定不将它们内联。
Clang14.0.0会展开循环,也会内联对func_A和func_B的两个调用。
请注意,如果更改示例的详细信息,特别是调用函数的数量,这些结果可能很容易更改。同样不明显的是,在这里内联函数调用是最好的决定。与cout <<语句相比,函数调用开销可以忽略不计。
函数上的inline关键字对这些行为没有影响。上面考虑的编译器的行为与它的行为完全相同。
inline可能是编译器的一个提示,即函数应该考虑内联。但这只是关键字的一个非常次要的目的。编译器也会考虑内联的非inline函数,并且主要使用内部启发式来决定内联是否合适。
inline关键字的主要用途是能够在头文件中定义函数。inline函数定义可以(与非inline函数定义相反)出现在多个翻译单元中。(实际上,inline函数必须在使用该函数的任何翻译单元中显示其定义。)这通过允许编译器直接在使用它的翻译单元中访问函数的定义来帮助内联。如果没有链接时间优化(LTO),编译器就不能真正地跨翻译单元内联函数调用。
如果一个函数无论如何只能在一个翻译单元中使用,那么它应该被标记为static,而不是inline,这样它就不会与其他同名的函数发生冲突,而其他函数应该是另一个翻译单元的本地函数。
https://stackoverflow.com/questions/73340220
复制相似问题