Bug 60583

Summary: Garbled data, "temporary bound ... only persists until the constructor exits", fine with clang++
Product: gcc Reporter: andreaskem
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: daniel.kruegler, jakub, jason
Priority: P3    
Version: 4.8.2   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Attachments: Problematic code

Description andreaskem 2014-03-19 11:19:23 UTC
Created attachment 32389 [details]
Problematic code

Hello,

I have a problem with the following code (boiled down from a larger source file exhibiting the problem):

//------------------------
#include <iostream>

using namespace std;

struct Vector {
  double x;
  double y;
  double z;
};

class Baz {
  private:
    Vector r;
    Vector u;

  public:
    Baz(const Vector& p, const Vector& v) : r{p.x,p.y,p.z}, u{v.x,v.y,v.z} {}

    const Vector& get_u() const {
      return(u);
    };

    void write() const {
      cout << "r: " << r.x << "," << r.y << "," << r.z << "; u: " << u.x << "," << u.y << "," << u.z << endl;
    };
};

class Foo {
  private:
    const Baz& b;

  public:
    Foo(const Baz& b_) : b{b_} {}
    void bar();
};

void Foo::bar() {
  b.write();
  int iters{10};
  b.write();
}

int main(void) {
  Baz b{Vector{0.5, 0.5, 0.5}, Vector{1e6, 0.1, 0.1}};
  Foo f{b};
  f.bar();
}
//------------------------

Compiling this with
---
$ g++ -Wall -Wextra -std=c++11 ~/test.cpp
---
leads to the following warnings:
---
***test.cpp: In constructor ‘Foo::Foo(const Baz&)’:
***test.cpp:33:27: warning: a temporary bound to ‘Foo::b’ only persists until the constructor exits [-Wextra]
***test.cpp: In member function ‘void Foo::bar()’:
***test.cpp:41:6: warning: unused variable ‘iters’ [-Wunused-variable]
---
and running the program shows that the data is garbled:
---
$ ./a.out
r: 6.95315e-310,2.07351e-317,0.5; u: 6.95315e-310,0.1,0.1
r: 6.95315e-310,2.07352e-317,0.5; u: 6.95315e-310,0.1,2.24932e-313
---

Using b(b_) instead of b{b_} seems to fix the first warning and the output. I don't quite understand what is happening here. Moreover, clang++ (3.3 or 3.4) does not print such a warning (it only complains about the unused iters variable) and the output is not garbled:
---
$ clang++ -Wall -Wextra -std=c++11 ~/test.cpp; ./a.out
***test.cpp:41:6: warning: unused variable 'iters' [-Wunused-variable]
        int iters{10};
            ^
1 warning generated.
r: 0.5,0.5,0.5; u: 1e+06,0.1,0.1
r: 0.5,0.5,0.5; u: 1e+06,0.1,0.1
---

What is going on here?

I tried two gcc versions, 4.7.2 and 4.8.2.
gcc version 4.7.2 (Debian 4.7.2-5)
(I am currently at work and have to use gcc 4.7.2 to create the .ii file attached to my report)
I first noticed the problem on my home computer with
gcc version 4.8.2 20140206 (prerelease) (GCC)

--------
Details:
gcc version 4.8.2 20140206 (prerelease) (GCC)
gcc version 4.7.2 (Debian 4.7.2-5)
clang version 3.4 (tags/RELEASE_34/final)
clang version 3.3 (tags/RELEASE_33/final)
Linux 3.13.6-1-ARCH #1 SMP PREEMPT Fri Mar 7 22:47:48 CET 2014 x86_64 GNU/Linux
Comment 1 Jakub Jelinek 2014-03-19 13:10:52 UTC
This got fixed with r207164 on the trunk, whether that change is backportable and desirable for 4.8 I'll leave to Jason.
Comment 2 Jonathan Wakely 2014-03-19 13:22:08 UTC
As this is DR1288 it's a dup of PR50025
Comment 3 andreaskem 2014-03-19 13:32:26 UTC
Thank you.

I looked around but did not find those reports. Sorry for that.
Comment 4 Paolo Carlini 2015-03-19 10:38:49 UTC
Dup then.

*** This bug has been marked as a duplicate of bug 50025 ***