在什么情况下内联函数不再是内联函数并充当任何其他函数?
3 回答
神话:
inline
只是编译器可能会或可能不会遵守的建议。一个好的编译器无论如何都会做需要做的事情。
真相:
inline
通常向实现表明,在调用点对函数体进行内联替换优于通常的函数调用机制。在调用点执行此内联替换不需要实现;但是,即使inline
省略了此替换,也会遵循其他规则(尤其是One Definition Rule)inline
。
在什么情况下,一个
inline
函数不再是一个inline
函数,而是充当任何其他函数?
鉴于引用的事实,这个问题有更深层次的背景。
当您将函数声明为static inline
函数时,该函数的行为就像任何其他static
函数一样,并且关键字inline
不再重要,它变得多余。
函数上的static
关键字强制inline
函数具有内部链接。(inline
函数具有外部链接)此类函数的每个实例都被视为单独的函数(每个函数的地址不同)并且这些函数的每个实例都有自己的副本静态局部变量和字符串文字(一个inline
函数只有一个副本)。
这是由编译器决定的。
但是有些情况不能内联,例如:
- 递归函数
- 地址在某处被引用的函数
- 虚函数(有一些例外的想法)
这取决于编译器优化。
不同的编译器有不同的规则来使代码更高效。但是,如果您将函数声明为内联函数,编译器往往会尊重您的决定,只要它的规则没有任何不同。
请记住,编译器可以完全改变方法的执行路径。例如,考虑下一种情况:
int MyClass::getValue()
{
return someVariable;
}
在编译时,将这种函数声明为内联与否几乎没有区别。可能编译器会将属性部分公开并编码:
myInstance->getValue()
作为
myInstance->someVariable
所以在大多数情况下,这更像是一个美学决定。