6

There are at least two places in C++ standard that prohibit defining objects with incomplete types (http://eel.is/c++draft/basic.def#5, http://eel.is/c++draft/basic.types#5). However, providing non-defining declarations for objects of incomplete type is generally allowed in C++. And I don't seem to be able to pinpoint the specific part that would prohibit declaring incomplete "objects" of void type in that fashion. (Granted, void is not an object type in C++, but neither are reference types, for one example.) So, is this

extern void a;

really ill-formed in C++?

In C providing non-defining declarations for void objects (as shown above) is allowed and both GCC and Clang accept the above in C code (definitions are not allowed, of course). But in C++ code both compilers issue errors for such declarations. Which part of the standard makes them to do so?

[basic.fundamental] lists possible uses of void type (http://eel.is/c++draft/basic.types#basic.fundamental-13) but it does not appear to be intended as a complete list.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • References (like pointers) form a *compound type* with the type they are applied to. So they are part of the type information of the variable being declared. – Galik Dec 30 '18 at 08:25
  • 1
    Possible duplicate of [Why can't we declare a variable of type void?](https://stackoverflow.com/questions/25853258/why-cant-we-declare-a-variable-of-type-void) – xskxzr Dec 30 '18 at 13:57

1 Answers1

7

I believe the relevant passages are the following:

[dcl.stc]

5 The extern specifier shall be applied only to the declaration of a variable or function.

[basic]

6 A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable's name, if any, denotes the reference or object.

[basic.types]

8 An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not cv void.

a, being a variable declaration, must denote a reference or an object according to [basic]¶6. That covers references which are indeed not object types. However, since void is neither a reference nor an object type, the declaration is ill-formed.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458