我知道在将inline关键字添加到类成员函数后,编译器决定内联“函数是否复杂”或函数体中是否存在“大量语句”。
什么被认为是“很多陈述”?
如果隐式或显式地使用函数的地址,编译器也无法执行内联。任何人都可以解释这一点吗?
因为内联只是一个建议,我该如何测试哪些函数没有内联?
答案 0 :(得分:4)
编译器是否内联生成代码取决于 编译器。大多数现代编译器都会产生很多 任何不是内联递归的东西。
这简直是假的。当地址被采取时, 编译器必须为地址生成一个外联副本,但是 这不会阻止函数在内联时进行内联 调用。
你没有。
答案 1 :(得分:4)
这完全取决于编译器;这可能取决于优化设置,目标体系结构的特性(例如函数调用的成本与由于代码大小增加而导致的缓存未命中的潜在成本)以及函数与其余代码的集成程度在特定的呼叫站点。
如果函数总是内联的,它本身就不再作为函数存在,因为它的指令直接放在调用站点上,其余的是调用者代码;因此,这样的函数不再具有地址,因为它与其调用者混合在一起。但是当你要求函数地址时通常会发生的事情是编译器会将函数内联到最喜欢的地方,但仍然将也作为“常规函数”发出,其地址通过函数指针使用
您可以反汇编生成的可执行文件,或者要求编译器发出程序集而不是构建完成的可执行文件(使用gcc
-S
选项)并手动检查它。尽管如此,请注意检查优化的二进制文件并不简单 - 因为内联代码与调用者代码混合在一起,可能很难找到内联函数的确切位置,同时您也可能会发现非内联的副本通过函数指针使用的函数(如上所述)。
答案 2 :(得分:2)
完全取决于编译器设计者决定使用什么启发法来决定是否内联函数调用。希望它基于生成的代码大小而不是“语句”的数量,这是一个完全没有意义的度量标准。希望它还包括对性能增益的估计,以衡量代码大小的任何增加。
如果获取了地址,那么必须有一个函数的非内联实例,以便获取地址。但是,如果编译器确定它们应该被内联,这不会阻止对函数的任何调用。
您可以反汇编生成的代码以查看是否存在函数调用。如果调用函数很大,或者它本身在另一个函数中内联,这可能会很棘手。大多数编译器都采用(非标准)强制内联的方式;但只有在你确定自己比编译器更清楚时才使用它,并且有测量来证明它。
答案 3 :(得分:1)
关于编译器何时可以内联检查此线程的问题:
Does the compiler decide when to inline my functions (in C++)?