4 回答
TA贡献1828条经验 获得超6个赞
inline111.cpp:
#include <iostream>void bar();inline int fun() { return 111;}int main() { std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun; bar();}
inline222.cpp:
#include <iostream>inline int fun() { return 222;}void bar() { std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;}
案例A:
编译:
g++ -std=c++11 inline111.cpp inline222.cpp
输出量:
inline111: fun() = 111, &fun = 0x4029a0inline222: fun() = 111, &fun = 0x4029a0
讨论:
即使您应该对内联函数有相同的定义,如果情况并非如此,C+编译器也不会标记它(实际上,由于 单独汇编它没有办法检查)。确保这一点是你自己的责任! 链接器不抱怨 一种定义规则,如 fun()
被宣布为 inline
..但是,因为 inline111.cpp是第一个翻译单元(它实际上调用 fun()
)由编译器处理,编译器实例化 fun()
在它 第一打电话 inline111.cpp..如果编译器决定 不扩大 fun()
应您程序中其他任何地方的要求( G.从… inline222.cpp)的电话 fun()
将始终链接到其生成的实例。 inline111.cpp(电话: fun()
内 inline222.cpp也可以在该翻译单元中生成一个实例,但它将保持不链接)。事实上,这一点从相同的 &fun = 0x4029a0
打印出来。 最后,尽管 inline
对编译器的建议 实际扩展一条龙 fun()
,它 视而不见你的建议很清楚,因为 fun() = 111
在这两条线上。
案例B:
编译 (通知反向命令):
g++ -std=c++11 inline222.cpp inline111.cpp
输出量:
inline111: fun() = 222, &fun = 0x402980inline222: fun() = 222, &fun = 0x402980
讨论:
这个案例证明了 案件A.注意一个重要的问题,如果您注释掉实际调用 fun()
在……里面 inline222.cpp (G.注释掉 cout
-声明 inline222.cpp完全)那么,尽管你的翻译单位的汇编顺序, fun()
中的第一次调用时将被实例化。 inline111.cpp的打印结果 案例B如 inline111: fun() = 111, &fun = 0x402980
.
案例C:
编译 (公告-O2):
g++ -std=c++11 -O2 inline222.cpp inline111.cpp
或 g++ -std=c++11 -O2 inline111.cpp inline222.cpp
输出量:
inline111: fun() = 111, &fun = 0x402900inline222: fun() = 222, &fun = 0x402900
讨论:
原样 在此描述 ,-O2
优化鼓励编译器 实际扩展
可以内联的函数(也请注意, -fno-inline
是 违约
没有优化选项)。从这里的输出可以看出, fun()
实际上 内联扩展
(根据它的定义 特别
翻译股),产生两个 异类
fun()
打印出来。尽管如此,还是有 只有一个
全局链接实例 fun()
(按照标准的要求),从 完全相同
&fun
打印出来。
TA贡献1786条经验 获得超11个赞
什么时候我不应该为C+中的函数/方法写关键字“内联”呢?
.cpp
编译器什么时候不知道什么时候使函数/方法‘内联’?
当一个应用程序为函数/方法写“内联”时,应用程序是否是多线程的?
- 4 回答
- 0 关注
- 612 浏览
添加回答
举报