AnT stands with Russia
AnT stands with Russia

Reputation: 320777

Non-defining declarations for `void` "objects": which part of C++ standard prohibits them? Or does it?

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.

Upvotes: 6

Views: 361

Answers (1)

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.

Upvotes: 7

Related Questions