首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gcc / c++11 :优化级别更改操作结果

gcc / c++11 :优化级别更改操作结果
EN

Stack Overflow用户
提问于 2015-10-04 10:39:04
回答 1查看 263关注 0票数 1

在C++类中,我重载了操作符-()。当我用-O0编译时,它的行为与预期一样,但是当我至少用-O1编译时,调用操作符-()的结果是错误的,尽管没有生成错误。

我不是C++大师,但在下面的代码片段中,没有什么是奇怪的。与我在这个站点上遇到的其他情况不同,我没有内联的asm,我没有调用库等等。代码中包含了所有的东西。

下面是我所用的gcc的版本:

代码语言:javascript
复制
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.

编译命令:

代码语言:javascript
复制
OK : g++ --std=c++11 -O0 -o test test.cpp
KO : g++ --std=c++11 -O1 -o test test.cpp

我收到了预期的警告:

代码语言:javascript
复制
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没有任何改变,因为它只是删除警告

下面是再现问题的代码片段:

代码语言:javascript
复制
#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;
}

如果我添加一个操作符-=()

代码语言:javascript
复制
  A& operator-=(const A& other) {
    this->val -= other.val;

    return *this;
  }

和主要变化:

代码语言:javascript
复制
A c = b - a;

使用

代码语言:javascript
复制
A c(b);
c -= a;

无论-Ox选项是什么,我都能很好地工作。

我怀疑从操作符-()返回对局部变量的引用是问题的根源(尽管c++11具有RVO特性?)。我不明白的是,为什么优化的水平会产生这样的效果?

毕竟,mys的代码有什么问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-04 10:54:53

您的operator-()正在返回对局部变量的引用。如果调用方使用该引用,则会导致它显示出未定义的行为。

按照惯例,operator-()按值而不是引用返回对象。这是有意义的,因为c = a - b通常保持ab不变,并给c它们之间的区别(不管定义如何)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32932563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档