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
It cannot be done on a void type
#include <iostream>
#include <cstring>
using namespace std;
extern void f; //compile-time error
int main()
{
}
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.