The following program...
int main()
{
int{1}.~int();
}
does not compile on (see conformance viewer):
clang++ trunk, with -std=c++1z
g++ trunk, with -std=c++1z
CL 19 2017
Introducing a type alias for int
...
int main()
{
using X = int;
int{1}.~X();
}
...makes the program valid on all previously mentioned compilers, without warnings (see conformance viewer).
Why is a type alias required when invoking int
's destructor? Is this because int
is not a valid grammar element for a destruction invocation?
It works because the grammar didn't make provisions for built-in types, but it did make provisions for aliases:
[expr.post]/1:
postfix-expression: postfix-expression . pseudo-destructor-name postfix-expression -> pseudo-destructor-name pseudo-destructor-name: ~ type-name ~ decltype-specifier
And [dcl.type.simple]/1:
type-name: class-name enum-name typedef-name simple-template-id
You can imagine what each variable under type-name
stands for. For the case at hand [expr.pseudo]/1 specifies that it is just a void
expression:
The use of a pseudo-destructor-name after a dot . or arrow -> operator represents the destructor for the non-class type denoted by type-name or decltype-specifier. The result shall only be used as the operand for the function call operator (), and the result of such a call has type void. The only effect is the evaluation of the postfix-expression before the dot or arrow.
The interesting thing to note, is that you should be able do that without an alias (if you have a named object), because the pseudo destructor call also works with a decltype
specifier:
auto a = int{1};
a.~decltype(a)();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With