Consider the following code, when will the temporary objects inside the MIL of C
be destructed? Temporaries are destructed when the full expression that lexically contains the creation of temporary finishes. However, is MIL even an expression? If so, what will the full expression in this case be?
#include <iostream>
class A {
public:
A() {
std::cout << "Default Constructor of A\n";
}
~A() {
std::cout << "Destructor of A\n";
}
};
class B {
public:
B() {
std::cout << "Default Constructor of B\n";
}
~B() {
std::cout << "Destructor of B\n";
}
};
class C {
A a;
B b;
public:
C() : a(A()), b(B()) {
}
};
int main() {
C c;
}
The output from Apple Clang compiled with -std=c++11 -fno-elide-constructors
shows
Default Constructor of A
Destructor of A
Default Constructor of B
Destructor of B
Destructor of B
Destructor of A
But I want to ask whether the following is also possible:
Default Constructor of A
Default Constructor of B
Destructor of B
Destructor of A
Destructor of B
Destructor of A
There are two things here, first for the literal question of
However, is MIL even an expression?
And that is yes. Per [intro.execution]/5.4 states
A full-expression is
[...]
5.4 - an init-declarator ([dcl.decl]) (including such introduced by a structured binding ([dcl.struct.bind])) or a mem-initializer ([class.base.init]), including the constituent expressions of the initializer,
so each initializer is a full expression and any temporary object is destroyed at the end.
Now, the second issue of the output, since C++17 the output has to be
Default Constructor of A
Default Constructor of B
Destructor of B
Destructor of A
because C() : a(A()), b(B())
is the same as C() : a(), b()
because of guaranteed RVO. This means there are no temporary objects and you just get the construction of the members in order of their declaration and then the destruction when c
goes out of scope in reverse order.
Pre C++17, without optimizations, then you could get the output
Default Constructor of A
Destructor of A
Default Constructor of B
Destructor of B
Destructor of B
Destructor of A
as seen in this live example.