Why isn't destructor for temporary object called after evaluating a full-expression:
#include <iostream>
struct A
{
int a;
A();
~A();
};
A::~A()
{
std::cout << "~A()" << std::endl;
}
A::A()
{
std::cout << "A()" << std::endl;
}
int main()
{
A b = A(); //Constructing of temporary object and applies copy-initalization
std::cout << "side effect" << std::endl;
//Destructor calling.
}
Output:
A()
side effect
~A()
But 12.2/3 [class.temporary] says:
When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.
With your compiler and options the temporary is elided (optimized away), which is permitted.
Thus there is no temporary.
Thus there is no missing constructor and destructor call pair.
It's also well worth noting that the copy and move constructors are the only constructors where the compiler is allowed to assume that the constructor has no side effects, even when it knows better.
C++11 §12.8/31:
” When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. […]