Is `template<typename>;` legal C++?
Asked Answered
P

2

16

GCC and Clang disagree on whether template<typename>; is a valid statement in C++ at global scope.

I'd expect it not to be allowed in the C++ standard because templatization pertains to declaration statements, not to expression statements and in consequence also not to null statements (the statement ;).

So, is this a bug in Clang?

Paramaribo answered 20/5, 2018 at 10:28 Comment(5)
It seems strange to me to use a semicolon when you are using template...Mongolia
It's not valid C++ according the standard. Clang is just being nice to you.Lindsy
Well since both compilers emit a diagnostic, both are conforming.Kilbride
@AntoineMorrier Templated class declarations and definitions always end in a semicolon.Bove
@Bove Yes but it is not placed right after the template<typename>Mongolia
C
13

Not really. The standard explicitly disallows such a declaration in [temp]p2;

The declaration in a template-declaration (if any) shall

  • declare or define a function, a class, or a variable, or

  • define a member function, a member class, a member enumeration, or a static data member of a class template or of a class nested within a class template, or

  • define a member template of a class or class template, or

  • be a deduction-guide, or

  • be an alias-declaration.

An empty-declaration doesn't match any of those clauses. Now the standard says that an implementation is required to issue a diagnostic message for any violation of its rules, like this one. Note that it says diagnostic, it doesn't specify whether a warning or an error (or even a note) is issued. The compiler can provide extensions that make what you wrote valid, as it wouldn't change the meaning of a well-formed program.

So no, both are right. However, clang's behavior is due to an extension, not something that the standard specifies.

Crest answered 20/5, 2018 at 11:6 Comment(6)
i wonder if such behavior on clang's part can break\change code's behavior where SFINAE is involved.Syndactyl
@Swift Nope. You cannot declare a template in the signature or in the template list. However, I would reasonably expect that clang ignores whatever extension it might have for SFINAE.Crest
this "extension" relates to all declarations, not only to template ones, but I see what you're meaning.Syndactyl
How do we distinguish between a null statement and an empty-declaration? Is it so that only declarations may appear at global scope?Paramaribo
@Crest The standard defines null statements in [stmt.expr]. null statements are expression statements whereas empty-declarations are declaration statements, so they're not the same thing. Yet, they both correspond to the same sequence of tokens: ; So how do we classify a ;?Paramaribo
@Paramaribo Oh I'm so sorry, I missed it. Ok so inside a compound statement there can only be a declaration-statement, which is a block-declaration. An empty-declaration is not a block-declaration.Crest
S
14

It's clang's idiosyncratic behavior that has existed for long time: missing declarations generate only a warning. It's just same as this:

int;

g++ would show an error, while clang will only show a warning. This doesn't contradict the standard.

warning: declaration does not declare anything [-Wmissing-declarations]

-Werror=missing-declarations sets things straight.

Syndactyl answered 20/5, 2018 at 11:3 Comment(0)
C
13

Not really. The standard explicitly disallows such a declaration in [temp]p2;

The declaration in a template-declaration (if any) shall

  • declare or define a function, a class, or a variable, or

  • define a member function, a member class, a member enumeration, or a static data member of a class template or of a class nested within a class template, or

  • define a member template of a class or class template, or

  • be a deduction-guide, or

  • be an alias-declaration.

An empty-declaration doesn't match any of those clauses. Now the standard says that an implementation is required to issue a diagnostic message for any violation of its rules, like this one. Note that it says diagnostic, it doesn't specify whether a warning or an error (or even a note) is issued. The compiler can provide extensions that make what you wrote valid, as it wouldn't change the meaning of a well-formed program.

So no, both are right. However, clang's behavior is due to an extension, not something that the standard specifies.

Crest answered 20/5, 2018 at 11:6 Comment(6)
i wonder if such behavior on clang's part can break\change code's behavior where SFINAE is involved.Syndactyl
@Swift Nope. You cannot declare a template in the signature or in the template list. However, I would reasonably expect that clang ignores whatever extension it might have for SFINAE.Crest
this "extension" relates to all declarations, not only to template ones, but I see what you're meaning.Syndactyl
How do we distinguish between a null statement and an empty-declaration? Is it so that only declarations may appear at global scope?Paramaribo
@Crest The standard defines null statements in [stmt.expr]. null statements are expression statements whereas empty-declarations are declaration statements, so they're not the same thing. Yet, they both correspond to the same sequence of tokens: ; So how do we classify a ;?Paramaribo
@Paramaribo Oh I'm so sorry, I missed it. Ok so inside a compound statement there can only be a declaration-statement, which is a block-declaration. An empty-declaration is not a block-declaration.Crest

© 2022 - 2024 — McMap. All rights reserved.