Why can't we declare a variable of type void?

user2953119 picture user2953119 · Sep 15, 2014 · Viewed 21.2k times · Source

I'm looking for a formal explanation of that fact in the Standard. I've found what 3.9.1/9 says and trying to give an explanation used that section.

Section 3.9.1/9, N3797:

The void type has an empty set of values. The void type is an incomplete type that cannot be completed. It is used as the return type for functions that do not return a value. Any expression can be explicitly converted to type cv void (5.4). An expression of type void shall be used only as an expression statement (6.2), as an operand of a comma expression (5.18), as a second or third operand of ?: (5.16), as the operand of typeid, noexcept, or decltype, as the expression in a return statement (6.6.3) for a function with the return type void, or as the operand of an explicit conversion to type cv void.

I don't understand how it implies from the fact that the void type has an empty set of values?

Suppose that type T has an empty set of values. Why does compiler throw an error when it come across the following line:

extern T v; 

We can decalre a variable of incomplete type in the following way:

#include <iostream>
#include <cstring>

using namespace std;

struct Foo;

extern Foo f; //OK!

int main()
{
}

and it works fine

DEMO

It cannot be done on a void type

#include <iostream>
#include <cstring>

using namespace std;

extern void f; //compile-time error

int main()
{
}

DEMO

Answer

Ben Voigt picture Ben Voigt · Sep 15, 2014

You cannot declare a variable of type void because variables must have object type or be references, extern void f; doesn't declare a reference, and void is not an object type:

Section 3 [basic] says that

A variable is introduced by the declaration of a reference other than a non-static data member or of an object.

Section 3.9 [basic.types] says that

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