在C++类中,我重载了操作符-()。当我用-O0编译时,它的行为与预期一样,但是当我至少用-O1编译时,调用操作符-()的结果是错误的,尽管没有生成错误。
我不是C++大师,但在下面的代码片段中,没有什么是奇怪的。与我在这个站点上遇到的其他情况不同,我没有内联的asm,我没有调用库等等。代码中包含了所有的东西。
下面是我所用的gcc的版本:
g++ (GCC) 4.9.3
Copyright © 2015 Free Software Foundation, Inc.
Ce logiciel est libre; voir les sources pour les conditions de copie.
Il n'y a PAS GARANTIE; ni implicite pour le MARCHANDAGE ou pour un BUT PARTICULIER.
g++ (GCC) 5.2.0
Copyright © 2015 Free Software Foundation, Inc.
Ce logiciel est libre; voir les sources pour les conditions de copie.
Il n'y a PAS GARANTIE; ni implicite pour le MARCHANDAGE ou pour un BUT PARTICULIER.编译命令:
OK : g++ --std=c++11 -O0 -o test test.cpp
KO : g++ --std=c++11 -O1 -o test test.cpp我收到了预期的警告:
test.cpp: In member function ‘A& A::operator-(const A&)’:
test.cpp:23:5: attention : reference to local variable ‘tmp’ returned
[-Wreturn-local-addr]
A tmp(*this);
^添加-Wno-返回-local-addr没有任何改变,因为它只是删除警告
下面是再现问题的代码片段:
#include <iostream>
using namespace std;
class A {
public:
double val;
A(int _val) : val(_val) {}
A() : val(0.0) {}
A(const A&) = default;
A(A&&) = default;
A& operator=(const A&) = default;
A& operator=(A&&) = default;
A& operator-(const A& other) {
A tmp(*this);
tmp.val -= other.val;
return tmp;
}
};
int main() {
A a(3);
A b(2);
A c = b - a;
cout << c.val << endl;
return 0;
}如果我添加一个操作符-=()
A& operator-=(const A& other) {
this->val -= other.val;
return *this;
}和主要变化:
A c = b - a;使用
A c(b);
c -= a;无论-Ox选项是什么,我都能很好地工作。
我怀疑从操作符-()返回对局部变量的引用是问题的根源(尽管c++11具有RVO特性?)。我不明白的是,为什么优化的水平会产生这样的效果?
毕竟,mys的代码有什么问题吗?
发布于 2015-10-04 10:54:53
您的operator-()正在返回对局部变量的引用。如果调用方使用该引用,则会导致它显示出未定义的行为。
按照惯例,operator-()按值而不是引用返回对象。这是有意义的,因为c = a - b通常保持a和b不变,并给c它们之间的区别(不管定义如何)。
https://stackoverflow.com/questions/32932563
复制相似问题