在C ++类中,我重载了operator-()。当我使用-O0进行编译时,它的行为与预期的一样,但是当我使用至少-O1进行编译时,尽管没有生成错误,但调用operator-()的结果是错误的。
我不是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-return-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;
}
并更改为main:
A c = b - a;
与
A c(b);
c -= a;
无论-Ox选项如何,我的工作都很完美。
我怀疑从operator-()返回对局部变量的引用是问题的根源(尽管c ++ 11的RVO功能?)。 我没有得到的是为什么优化水平会产生这样的影响?
毕竟,mys代码有问题吗?
答案 0 :(得分:3)
您的operator-()
正在返回对本地变量的引用。这会导致调用者在使用该引用时显示未定义的行为。
传统上,operator-()
按值返回对象,而不是按引用返回。这是有道理的,因为c = a - b
通常会使a
和b
保持不变,并给出c
它们之间的差异(无论如何定义)。