Description
Since Richard Smith’s proposal P0593R6, a pseudo-destructor call ends the lifetime of a scalar object:
3.6. Pseudo-destructor calls
In the current C++ language rules, "pseudo-destructor" calls may be used in generic code to allow such code to be ambivalent as to whether an object is of class type:
template<typename T> void destroy(T *p) { p->~T(); }When T is, say, int, the pseudo-destructor expression p->~T() is specified as having no effect. We believe this is an error: such an expression should have a lifetime effect, ending the lifetime of the int object. Likewise, calling a destructor of a class object should always end the lifetime of that object, regardless of whether the destructor is trivial.
This change improves the ability of static and dynamic analysis tools to reason about the lifetimes of C++ objects.
So doesn’t the statement 0 .T::~T();
given in [expr.prim.id.dtor]/3 produce undefined behavior now that it destroys the temporary object 0 twice?
[Example 1:
struct C { }; void f() { C * pc = new C; using C2 = C; pc->C::~C2(); // OK, destroys *pc C().C::~C(); // undefined behavior: temporary of type C destroyed twice using T = int; 0 .T::~T(); // OK, no effect 0.T::~T(); // error: 0.T is a user-defined-floating-point-literal ([lex.ext]) }— end example]