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?