After a function is called, when the local (non-static) objects will be destroyed has been vague to me, especially after C++17 where prvalue is redefined. So I decide to ask this question.
(In C++14 and earlier)
Assume there is no optimization, consider the following toy code:
class Y
{
public:
~Y() { cout << "quitting f()\n"; }
};
class X
{
public:
X& operator=(const X& x)
{
cout << "assignment\n";
return *this;
}
};
X f()
{
X x;
Y y;
return x;
}
int main()
{
X x;
x = f();
}
The outputs are as follows:
quitting f()
assignment
Question 1:
In my current understanding, the local variables of f() are destroyed immediately after the returned temporary is created. May I ask if this is true?
(In C++17 and newer)
Consider the following toy code:
class Z { };
class Ya
{
public:
~Ya() { cout << "quitting f1()\n"; }
};
class Yb
{
public:
~Yb() { cout << "quitting f2()\n"; }
};
class X
{
public:
X() {}
X(Z z) { cout << "constructing X\n"; }
X& operator=(const X& x)
{
cout << "assignment\n";
return *this;
}
};
X f1()
{
Z z;
Ya y;
return X(z);
}
X f2()
{
Yb y;
return f1();
}
int main()
{
X x;
x = f2();
}
The outputs are as follows:
constructing X
quitting f1()
quitting f2()
assignment
In my current understanding, X(z) is a prvalue which is used to initialize the prvalue represented by f1(), which is then used to initialize the prvalue represented by f2(). The prvalue represented by f2() is then materialized into a temporary which is then used in the copy assignment.
If my understanding to question 1 is correct, I would guess that the local variables z and y are destroyed immediately after the initialization of the prvalue represented by f1(). Assume this is true, there is a problem: before the prvalue represented by f2() is materialized, there is NO object constructed from X(z) exists, so how could the materialized temporary be created from X(z) at the point when z is already destroyed?
Question 2:
As a result, my guess is that the local variables of f1() are destroyed after the prvalue represented by f2() is materialized (or if the prvalue is used to initialize a variable, had we written X x = f2(); instead). May I ask if this is true?