4

Generally this discussion is up to the local function variable only:

void foo (const int &i)
{
  // use i till foo() ends
}
foo(3);

But, does this rule applies to the class member also ?

struct A {
  const int &a;
  A () : a(3) {}  // version 1
  A (const int &i) : a(i) {} // version 2
};

Now A used as,

{
  return ()? new A : new A(3) : new A(some_local_variable);
}

Will the contents of a remain same through out the life time of the all 3 newly allocated A ?

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • In general, the lifetime is not long enough. From 12.2/5: "A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call." See http://stackoverflow.com/questions/2604206/c-constant-reference-lifetime/2604269#2604269 for full details. – Michael Burr Jul 16 '11 at 05:00
  • I should note, however, that binding the const reference to the literal `3` is fine since no temporary is generated and the lifetime of the literal exceeds the lifetime of the `A` object. However, if a conversion were necessary, then this wouldn't hold. – Michael Burr Jul 16 '11 at 05:22

2 Answers2

3

The C++03 standard (Section "12.2/5 Temporary objects") answers your question aptly:

The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits. A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
2

If you allocate an object using new, it will remain in memory forever - until you delete it. It's not a temporary object.

a is a member of A, and as such part of the allocation.

EDIT: Thanks for the comments. I would say - no, this is not correct. Consider this:

struct A {
  const int &a;
  A () : a(3) {}  // version 1
  A (const int &i) : a(i) {} // version 2
};

void foo() {
  A *pA;

  {
     int x;
     pA = new A(x);
  }

  // Now pA->a is pointing to the address where `x` used to be,
  // but the compiler may very well put something else in this place now
  // because x is out of scope.
}

The answer is more obvious if the lifetime of the A object spans across several functions.

Side note: I find the word "contents" a bit ambiguous here. Equate the reference with a pointer, so your a is basically pointing to an integer. const or not, if the integer does no longer exist (because it was on the stack and has been removed), your a - while still pointing to the same address in memory - is referencing something else now. The GotW article appears to be talking about the compiler prolonging the lifetime of the object being pointed to by the reference. The reference itself, again, is just a pointer.

EboMike
  • 76,846
  • 14
  • 164
  • 167
  • I think the OP is asking if [the situation described in GotW #88](http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/) applies to `const` reference data members as well. – In silico Jul 16 '11 at 04:46
  • I am meaning contents of `a`. – iammilind Jul 16 '11 at 04:49
  • 1
    Sorry, I misread. That's actually a good question, and I'm tempted to say NO, it is not valid, since the issue is more about the validity of the object being referenced. However, I will probably delete my answer since that's just my guess. – EboMike Jul 16 '11 at 04:51
  • No, in your example `pA` is not out of scope; it's allocated a valid memory location with `new A`. My only concern is about `A::a`, which is still a question. – iammilind Jul 16 '11 at 04:56
  • I wasn't being clear. `x` is out of scope, and as such A::a is pointing to a memory address that is potentially something other than `x`. – EboMike Jul 16 '11 at 04:58