考虑下面的C ++代码:
#include <iostream>
using namespace std;
class A
{
int a;
public:
A();
void f();
};
A::A()
{
cout<<"Constructor"<<endl;
}
inline void A::f()
{
cout << "hello\n";
}
int main()
{
A a;
a.f();
a.f();
a.f();
return 0;
}
这里函数f由我内联。现在我运行size命令来查找文本部分的大小。我得到了以下输出:
text data bss dec hex filename
2148 312 144 2604 a2c ./1
现在我通过从定义中删除inline关键字使函数f非内联。我再次运行了size命令:
text data bss dec hex filename
2148 312 144 2604 a2c ./1
因此,文本部分的大小在两种情况下都是相同的,尽管我希望f在内联的情况下大小更大,因为在内联的情况下它的调用只是被代码替换。
那么,这可能是什么原因?是否有任何尺寸会改变的例子?
答案 0 :(得分:3)
inline
不会影响函数调用是否内联(尽管它可能会或可能不会影响编译器的决策)。编译器可以在“as-if”规则下自由内联任何函数调用,只要它不改变程序的行为,就允许任何优化。
inline
的目的是允许您在标题中定义函数,给出多个定义(每个翻译单元中包含标题的一个定义),否则单一定义规则将禁止这些定义。对于某些编译器,这是允许内联函数调用所必需的 - 除非它具有链接时优化器,编译器只能在定义可用时内联调用函数。
如果您正在使用GCC,那么如果您想看到效果,可以使用一个属性来阻止内联:
void f() __attribute__ ((noinline));
答案 1 :(得分:2)
由于您将所有代码都放在一个文件中,因此编译器很可能在两种情况下都内联A::f
。
Here is a demo在您的代码中显示此内容。
比检查文本部分大小更好,您可以指定-S
编译器选项并比较两个版本的程序集输出。
答案 2 :(得分:1)
在这种情况下,这可能是链接时间优化的情况。使用g++ -S 1.cpp
编译代码的事实证明了这一点。
内联的汇编代码的大小大于非内联的汇编代码的大小。因此,实际行为在汇编中看到,但在链接时间之后不在最终可执行文件中。
答案 3 :(得分:0)
inline只是对编译器的请求。它可能会也可能不会执行内联函数。