3

This simple program is accepted by EDG (ICC) but rejected by GCC and Clang.

Is it well formed? If not, why?

int main() {
    int n;
    n.~int();
}

To the curious: The program doesn't do anything and I rather doubt there's even a use case for this language feature. There's templates, but whether they generate expression syntax is debatable. Such topics aren't appropriate for this site. Nothing to see here.


EDIT: The title of this question is odd. I thought the issue was the lack of an int:: qualifier before ~int. The question was inspired by this Q&A, which encourages omission of the qualifier when invoking something like derived_object::~base_class(). This however is ill-formed and only accepted by GCC.

Community
  • 1
  • 1
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 1
    Dang, I was about to take from a comment I read how long ago, but it's [your comment](http://stackoverflow.com/questions/3498730/why-is-c-not-an-object-oriented-language/3544556#comment3655901_3498750). – chris Aug 22 '14 at 01:17
  • @chris Actually that's insightful, at that time I noted that a `typedef int INT` was needed "for syntax sake." And indeed, `int` is not a *type-name*. – Potatoswatter Aug 22 '14 at 01:20
  • The use case for this is `std::allocator::destroy()`. – T.C. Aug 22 '14 at 01:44
  • @T.C. That's a template, and a two-phase template engine doesn't generate grammar productions upon instantiation. But, this is the topic I mentioned avoiding in the postscript. – Potatoswatter Aug 22 '14 at 01:47

3 Answers3

4

I believe this is ill-formed because ~int is not a valid pseudo-destructor-name. According to the grammar at §5.2/1, in a pseudo-destructor-name the tilde must be followed by a type-name or decltype-specifier. A type-name is a class-name, enum-name, typedef-name, or simple-template-id (§7.1.6.2/1), and int is none of these, so int is not a type-name (although it is a type-specifier).

(References taken from N3936, i.e. the C++14 draft.)

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
3

A pseudo-destructor-name is (§5.2 [expr.post]/p1):

pseudo-destructor-name:
    nested-name-specifier_opt type-name :: ~ type-name
    nested-name-specifier template simple-template-id :: ~ type-name
    nested-name-specifier_opt~ type-name
    ~ decltype-specifier

A type-name is (§7.1.6.2 [dcl.type.simple]/p1):

type-name:
    class-name
    enum-name
    typedef-name
    simple-template-id

Hence, int is not a type-name, so n.~int(); is not well-formed.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • Doesn't 5.2.4/2 say that the types shall be of scalar type, which is what `int` is? – David G Aug 22 '14 at 01:28
  • @0x499602D2 `int` isn't a *type-name*, so `~int` doesn't even get past the syntax check, and the semantic constraints on the type don't even come into play. – T.C. Aug 22 '14 at 01:37
2

The pseudo-destructor-name grammar productions all require type-name identifiers, not simple-type-specifiers which is what int is.

So, this is an EDG bug, which is unusual.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421