[英]Unexpected optimization happens when declaring object and calling function with it in the same line
I know it is not the best practice writing code like this, but it just happened.我知道编写这样的代码并不是最佳实践,但它就这样发生了。
It is basically about a function like它基本上是关于 function 之类的
C &foo(C &c); // will assign value to c and return c
and a line initializing an object by a self-assignment through the function, like以及通过 function 自分配初始化 object 的行,例如
C c = foo(c);
Here is my simplified code:这是我的简化代码:
class C {
public:
C(int i): _i(i) {}
C(const C& c): _i(c._i){}
int _i;
};
C &foo(C &c) {
c = 10;
return c;
}
int main() {
C c = foo(c);
cout << c._i << endl;
return 0;
}
The function yields different result if compiled with -O3.如果使用 -O3 编译,function 会产生不同的结果。 Without optimization, the result is 10 as expected.如果不进行优化,结果如预期的那样为 10。 With -O3, the result becomes 0. I know gcc must optimize away something, most likely about the constructor of C, but I cannot figure it out.使用 -O3,结果变为 0。我知道 gcc 必须优化一些东西,很可能是关于 C 的构造函数,但我无法弄清楚。
If C is replaced with a primitive type, eg int, then the function yields the same result between optimized and non-optimized code.如果 C 被替换为原始类型,例如 int,则 function 在优化和非优化代码之间产生相同的结果。
This has nothing to do with optimisation;这与优化无关; your program's behaviour is not well-defined.您的程序的行为没有明确定义。 When you change some compiler settings you observe the consequences of that.当您更改某些编译器设置时,您会观察其后果。
When you pass a reference to c
into foo
, it has not yet been initialised.当您c
的引用传递给foo
时,它还没有被初始化。 You are allowed to use it but only in limited ways.您可以使用它,但只能以有限的方式使用。 Here you assign a result to it.在这里,您为其分配一个结果。 Then you return the reference again.然后你再次返回参考。 Then it is copy-initialised from itself.然后它从自身复制初始化。 Clearly an initialisation cannot happen after an assignment.显然,在赋值之后不能进行初始化。
Rework your approach.重新设计你的方法。
Why not make it simple?为什么不让它变得简单呢?
C c;
foo(c);
Remember that the "assignment" in the definition is really copy-construction.请记住,定义中的“赋值”实际上是复制构造。 With和
C c = foo(c);
what you do is equivalent to你所做的相当于
C c(foo(c));
And the problem here is that when foo(c)
is called, the object c
haven't been constructed yet, leading to undefined behavior!这里的问题是,当调用foo(c)
时,object c
尚未构建,导致未定义的行为!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.