Home > Software design >  c object lifetime extension rules with member initializers
c object lifetime extension rules with member initializers

Time:11-20

In this talk, the author mentions lifetime extension rules extend to member initializers based on the standard. I see the opposite though, i.e. ~Y is called before "Hello" is printed below. Is the author referring to something else?

#include <iostream>
using namespace std;

struct Y {
   ~Y() { 
      cout << __PRETTY_FUNCTION__ << "\n";
   }
   Y() { 
      cout << __PRETTY_FUNCTION__ << "\n";
   }
};

struct X {
   ~X() { 
      cout << __PRETTY_FUNCTION__ << "\n";
   }
   X(const Y& y) : ref(y) { 
      cout << __PRETTY_FUNCTION__ << "\n";
   }
   const Y &ref;
};

Y gety() { 
   return {};
}

X getx() { 
   return gety();
}

int main() {
   const X &ref = X{Y{}};
   cout << "Hello\n";
}

The output is

Y::Y()
X::X(const Y&)
Y::~Y()
Hello
X::~X()

Edit: I see a difference with the following update that does aggregate initialization

struct X {
   ~X() { 
      cout << __PRETTY_FUNCTION__ << "\n";
   }
   /*
   X(const Y& y) : ref(y) { 
      cout << __PRETTY_FUNCTION__ << "\n";
   }
   */
   const Y &ref;
};

int main() {
   const X &ref = X{Y{}};
   cout << "Hello\n";
}

in which case the output is

Y::Y()
Hello
X::~X()
Y::~Y()

CodePudding user response:

It applies only in the case of aggregate initialization, because otherwise there is a constructor call and the prvalue would be bound to the reference parameter of that constructor, not directly to the reference member.

Also, it does not apply to aggregate initialization with parentheses instead of braces in C 20 and later. (There is a specific exception for this case.)

  • Related