1

Binding a temporary to a const reference extends its lifetime; cf. GotW #88.

Why does not this work on this snippet? Live here.

#include <iostream>
#include <string>

struct A {
    A() : s("abc") {}
    const std::string& s;
};

struct B {
    const std::string& s = "def";
};

int main() {
    A a;
    std::cout << a.s << std::endl;
    B b;
    std::cout << b.s << std::endl;
}

Bonus question: How to trigger a warning with gcc?

unagi
  • 428
  • 3
  • 15
  • Quoting the GotW you linked: "Note this only applies to stack-based references. It doesn’t work for references that are members of objects". – molbdnilo Nov 27 '15 at 06:13
  • Yes, it is what R Sahu mentioned in his answer. Thank you. – unagi Nov 27 '15 at 06:55

4 Answers4

3

In the article that you linked to, you will find:

(Note this only applies to stack-based references. It doesn’t work for references that are members of objects.)

That's why the references in a and b are not valid. They don't extend the life of the temporaries.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
3

From C++14 [class.temporary]/5:

The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

  • A temporary bound to a reference member in a constructor’s ctor-initializer persists until the constructor exits.

  • [...]

M.M
  • 138,810
  • 21
  • 208
  • 365
1

cppreference.com says:

a temporary bound to a reference member in a constructor initializer list persists only until the constructor exits, not as long as the object exists.

http://en.cppreference.com/w/cpp/language/reference_initialization

Dániel Sándor
  • 1,246
  • 8
  • 14
  • Thanks, I very much prefer the wording of cppreference to the standard’s. There is a note saying until C++14, however, and I compiled my code with the gcc flag `-std=c++14`. Do you know what is different? – unagi Nov 27 '15 at 08:05
  • Your welcome! Wikipedia says C++14 is the informal name for the most recent revision of the C++ ISO standard. [https://en.wikipedia.org/wiki/C%2B%2B14] I guess it means that the rule we are talking about will be changed in the next formal standard or it is very probable to be changed. But I am not sure. – Dániel Sándor Nov 28 '15 at 04:41
0

The lifetime is only extended to the end of the compiler generator constructor for B. When the constructor returns, the temporary string created to hold "def" will be destroyed leaving you with a dangling reference.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Why so? The reference `s` does not go out of scope and has the same lifetime as the struct. – unagi Nov 27 '15 at 06:11
  • Because of how inline initializers are handled by the compiler. A constructor will be generated to do the initialization and that's the scope that has the lifetime of the temporary. – 1201ProgramAlarm Nov 27 '15 at 06:13