-fno-inline
-O0
__attribute__ ((noinline))
dummy asm("")
没有成功! 代码如下:
#include<iostream>
using namespace std;
struct A {
A() {cout << "A::A()" <<endl; }
A(const A& a) {cout << "A::A(copy)" <<endl; }
A& operator=(const A& a) {cout << "A::=()" <<endl; return *this;}
};
A __attribute__ ((noinline)) func()
{
cout << "func()" << endl;
A loc;
asm("");
return loc;
}
int main() {
A a = func();
}
这个(g ++(Ubuntu / Linaro 4.5.2-8ubuntu4)4.5.2)的不幸输出是
func()
A::A()
声明A a = func(); ??
这个实验的原因是我想知道执行到这个语句时会发生什么(因为我需要控制如何完成):
A a = func();
我读到了复制构造函数被调用时
A a = b;
(在这种情况下,复制构造函数被调用。但不是在A a = func();)的情况下 该函数是内联的。因为我的“结构A”,我需要控制这个语句 在现实生活中包含需要处理的动态分配数据。
我错过了一些明显的东西吗?!
答案 0 :(得分:18)
不,这与内联函数无关。内联函数不会改变可观察的行为。
这是一个名为copy elision的优化,它允许编译器通过直接在目标处构造返回值来避免复制。您可以使用g ++标志-fno-elide-constructors
禁用它。
在任何情况下,动态分配的数据应该不是问题。假设一个理智的复制构造函数,您将看到的唯一区别可能是更好的性能。
答案 1 :(得分:6)
如果struct A
包含动态分配的数据,那么您有责任在适当的析构函数/构造函数中管理该内存。许多类管理动态分配的数据,并且使用椭圆形副本工作得很好。 RVO和NRVO是重要的优化。
答案 2 :(得分:3)
如果有人(像我一样)真的在寻找避免inline
:
-fkeep-inline-functions -fno-inline
-fkeep内联函数
即使集成了对给定函数的所有调用,并且该函数被声明为静态,但仍然输出该函数的单独的运行时可调用版本。此开关不会影响外部内联函数。-fno列直插
不要注意内联关键字。通常,此选项用于防止编译器扩展任何内联函数。请注意,如果您没有进行优化,则不能内联扩展任何功能。