【发布时间】:2012-03-19 09:05:46
【问题描述】:
如果我没有将函数 f 声明为内联。如下:
啊哈:
X f(Y y);
A.cpp:
X f(Y y)
{
...
}
然后在不同的翻译单元中:
B.cpp:
#include "A.h"
Z g(W w)
{
...
... f(...) ...
...
}
然后我用gcc 4.6编译两个翻译单元A.o和B.o,然后也通过gcc链接它们。 (可能在两个步骤中都使用 -O3)
gcc 会考虑在链接时内联函数以提高性能吗?还是为时已晚?
在一次代码审查中,有人建议我不应该将我的函数声明为内联,因为编译器比我何时内联更清楚。除非函数在头文件中定义,否则我总是印象深刻,编译器没有内联它的选项。
(如果 C 模式、C++ 模式或 gnu++0x 模式的答案不同,请同时指出)
【问题讨论】:
-
为什么要做这样的事情?
inline就是为此而发明的。它允许您在头文件中定义函数,而不会出现“多个定义的符号”错误。现在它工作得很好,编译器有很好的策略来有效地内联函数。 -
@JensGustedt:为什么?懒惰。我宁愿优化器确定何时最好内联函数,就像它确定何时将局部变量放入寄存器而不是堆栈一样。我认为这是一个没有争议的观点,而你没有抓住重点。
-
嗯,这正是我所说的。让编译器有机会为你做这件事。
inline除了要求编译器在适当的时候执行之外,没有别的意思。为了与您的示例保持一致,局部变量在编译器决定将其保存在寄存器中或溢出时是完全可见的。编写干净的代码,编译器会对你很好。坦率地说,为什么在头文件中定义函数比在 .c 中更难?完全相同的文字出现在不同的地方? -
@JensGustedt:所以现在你建议所有函数都应该在标题和
inline中定义?两个问题(1)修改实现会导致接口依赖(以及随之而来的连锁反应)重新编译,(2)inline 关键字会使每个函数签名变得混乱。 -
我在哪里说“全部”?
inline不是签名的一部分,AFAIK。而你所要求的,链接时间“内联”会在代码之间引入比这更微妙的依赖关系。