当前位置:  开发笔记 > 编程语言 > 正文

内联函数具有非内联副本

如何解决《内联函数具有非内联副本》经验,为你挑选了1个好方法。

在Agner Fog的优化C++手册中,他有一节"内联函数有一个非内联副本",他写道

函数内联具有复杂性,即可以从另一个模块调用相同的函数.编译器必须制作内联函数的非内联副本,以便可以从另一个模块调用该函数.如果没有其他模块调用该函数,则此非内联副本为死代码.代码碎片化使得缓存效率降低.

让我们为此做一个测试.

foo.h中

inline double foo(double x) {
    return x;
}

t1.cpp

#include "foo.h"
double t1(double x) {
    return foo(x);
}

main.cpp中

#include 
extern double foo(double);

int main(void) {
    printf("%f\n", foo(3.14159));
}

编译,g++ t1.cpp main.cpp并正确运行.如果我这样做g++ -S t1.cpp main.cpp并查看程序集,我看到它main.s调用了一个定义的函数t1.s.这样做g++ -c main.cppg++ t1.cpp看着这些符号nm显示U _Z3foodmain.oW _Z3foodt1.o.所以很明显,Agner声称存在非内联副本是正确的.

怎么样g++ -O1 t1.cpp main.cpp由于foo未定义,因此无法编译. 做的g++ -O1 t1.cppnm t1.o显示_Z3food已被剥离.

现在我很困惑.我没想到g ++会在启用优化的情况下删除非内联副本.

似乎启用优化inline等同于static inline.但是没有优化inline意味着生成了非内联副本.

也许GCC认为我不会想要非内联副本.但我能想到一个案例.假设我想创建一个库,并且在库中我想要一个在多个转换单元中定义的函数(这样编译器可以在每个转换单元中内联函数的代码)但我还想要一个外部模块链接到我的库到能够调用库中定义的函数.我显然需要一个非内联版本的功能.

Agner给出的一个建议是,如果我不想使用非内联副本static inline.但是从这个问题和答案我推断,这只是为了显示意图.所以一方面很明显它不仅仅是意图而不使用优化,因为它创建了非内联副本.但另一方面,通过优化,它实际上似乎只显示了意图,因为非内联副本被剥离了.这令人困惑.

我的问题:

    在启用优化的情况下,GCC是否正确剥离非内联副本?换句话说,如果我不使用,应该总是有非内联副本static inline吗?

    如果我想确定我不应该使用非内联副本static inline


我才意识到我可能误解了Agner的陈述.当他说函数inlinng时,他可能会向编译器倾斜代码而不是使用inline关键字.换句话说,他可能指的是externinline或不用或定义的函数static.

例如

//foo.cpp
int foo(int x) {
    return x;
}

float bar(int x) {
    return 1.0*foo(x);
}

//main.cpp
#include     
extern float bar(int x);    
int main(void) {
    printf("%f\n", bar(3));
}

使用内联的gcc -O3 foo.cpp main.cpp节目foo进行编译,bar但是foo从未使用过的非内联副本在二进制文件中.



1> Baum mit Aug..:

该标准规定,方法的完整定义inline需要在每个使用它的翻译单元中可见:

内联函数应在每个使用过的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2).[......]如果在一个翻译单元中内联宣布具有外部联系的函数,则应在其出现的所有翻译单元中内联声明; 无需诊断.

(N4140中的7.1.2/4)

这确实使你的问题中的例子形成了错误.

此规则还包括链接库的外部模块中的每个TU.他们还需要C++代码中的完整定义,例如通过在头文件中定义函数.因此,如果当前转换不需要,编译器可以安全地省略任何类型的"非内联副本".

关于确定副本不存在:标准不保证任何优化,因此由编译器决定.有和没有额外的static关键字.

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有