未在函数结果上调用复制构造函数
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” 现实生活中包含需要处理的动态分配的数据。
我在这里错过了一些明显的东西吗?
GCC inlines a statement -- no matter how hard I try to prevent it. I tried
-fno-inline
-O0
__attribute__ ((noinline))
dummy asm("")
No success!
Here the code:
#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();
}
The unfortunate output of this (g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2) is
func()
A::A()
What happened to the statement A a = func(); ??
The reason for this experiment is that I would like to know what happens when execution comes to this statement (because I need control how this is done):
A a = func();
I read that the copy constructor is called when one does
A a = b;
(In this case the copy-constructor is called. But not in the case A a = func();)
The function is inlined instead. I NEED control over this statement since my "struct A"
in real life contains dynamically allocated data that needs to be taken care of.
Am I missing something obvious here ?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,这与内联函数无关。内联函数不会改变可观察的行为。
这是一种称为复制省略的优化,它允许编译器通过直接在目标构造返回值来避免复制。您可以使用 g++ 标志
-fno-elide-constructors
禁用它。无论如何,动态分配的数据应该不成问题。假设有一个健全的复制构造函数,您将看到的唯一区别可能是更好的性能。
No, this has nothing to do with the function being inlined. Inlining the function would not change observable behaviour.
This is an optimization called copy elision that allows the compiler to avoid a copy by constructing the return value directly at the destination. You can disable it with the g++ flag
-fno-elide-constructors
.In any case, the dynamically allocated data should not be a problem. Assuming a sane copy constructor, the only difference you will see will be possibly better performance.
如果 struct A 包含动态分配的数据,那么您有责任在适当的析构函数/构造函数中管理该内存。许多类管理动态分配的数据并且可以很好地处理省略副本。 RVO 和 NRVO 是重要的优化。
If
struct A
contains dynamically allocated data, then it's your responsibility to manage that memory in the appropriate destructor/constructor. Many classes manage dynamically allocated data and work just fine with ellided copies. RVO and NRVO are important optimizations.如果有人(像我一样)真的想避免内联:
In case anyone (like me) is really looking for avoiding
inline
: