GCC概述了一个声明 - 无论我多么努力地阻止它。我试过了
-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()的情况下;)函数是内联的。我需要控制这个语句,因为我现实生活中的“struct A”包含需要处理的动态分配数据。
我在这里错过了一些明显的东西吗?
不,这与内联函数无关。内联函数不会改变可观察的行为。
这是一种称为复制省略的优化,它允许编译器通过直接在目标处构造返回值来避免复制。您可以使用g ++标志-fno-elide-constructors
禁用它。
无论如何,动态分配的数据应该不是问题。假设一个理智的复制构造函数,您将看到的唯一区别可能是更好的性能。
如果struct A
包含动态分配的数据,那么您有责任在适当的析构函数/构造函数中管理该内存。许多类管理动态分配的数据,并且使用椭圆形副本工作得很好。 RVO和NRVO是重要的优化。
如果有人(像我)真的想要避免inline
:
-fkeep-inline-functions -fno-inline
-fkeep内联函数 即使集成了对给定函数的所有调用,并且该函数被声明为静态,但仍然输出该函数的单独的运行时可调用版本。此开关不会影响外部内联函数。
-fno内联 不要注意内联关键字。通常,此选项用于防止编译器扩展任何内联函数。请注意,如果您没有进行优化,则不能内联扩展任何功能。