Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicitly invoking `int` destructor - why is a type alias required? [duplicate]

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?

like image 453
Vittorio Romeo Avatar asked Sep 26 '17 14:09

Vittorio Romeo


1 Answers

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)();
like image 146
StoryTeller - Unslander Monica Avatar answered Nov 06 '22 19:11

StoryTeller - Unslander Monica