什么时候编译器不必将内联函数标记为内联

when does the compiler necessarily not make a function marked inline as inline

本文关键字:记为 函数 编译器 什么时候 不必      更新时间:2023-10-16

什么时候编译器不一定把内联的函数标记为内联的?

最明显的是,当你使用指向函数的指针时,它不能内联函数。如果传递指针并(可能稍后)决定通过指针调用函数,编译器必须生成函数的非内联版本。当然,如果函数是直接调用的,编译器可能仍然会内联它。编译器也可以自由地不内联函数。

使用inline关键字仅仅是对编译器的一个提示,您建议在使用的地方内联展开它。然而,在预测高级CPU特性(如L1和L2缓存以及分支预测管道)可能对性能产生影响方面,编译器要比您聪明得多。如果编译器认为内联函数会使代码变慢,或者不可接受地变大,它就不会内联它。或者,如果由于语法依赖而不能,例如其他代码使用函数指针进行回调,或者将函数导出到外部,如动态/静态代码库中。

如果问题是编译器不能以任何方式内联函数,这里有几个答案。

定义时,如果一个函数是递归的,递归级别取决于参数,而不是尾递归,那么它就不能内联(在编译时不可能知道该函数将有多少次迭代)。一般来说,不显示尾递归的递归函数不是内联的(即使在编译器可以推断递归步骤的情况下)。

当在不可见指针初始化的上下文中通过指针使用时。

如果问题不是什么时候保证不内联,而是什么事情可以使编译器避免内联,还有一些其他的。例如,函数的复杂性和大小,它是否有循环,它已经在做的内联级别(f调用g调用h调用i…所有这些都可能被内联,但如果调用的数量足够深,编译器倾向于放弃)....还有其他的。您可以尝试从编译器供应商那里找到他们运行哪种类型的启发式来确定何时内联。