How is void *a = &a legal?

Consider the following C++ code:

void* a = &a;

Why doesn't the compiler complain for using an undeclared identifier?

Also, what does the compiler consider the variable a to be? Is it a pointer to a void object or is it a pointer to a void* pointer?


Solution 1:

The scope of declaration of variables in C++ can be pretty surprising:

void* a =               &a;
         ^~~~~~~~~~~~~~~~~
          a declared as `void*` from here on

Therefore, &a is void** but since any pointer type is implicitly convertible to void*...

Solution 2:

It is equivalent to

void* a;
a = &a;

Therefore, a has been declared. So a gets the address of a written in a. So it is a pointer to a void pointer. (You did not define any objects yet.)

Solution 3:

In void* a, a is declared as a pointer not to a void type but to "any" type (special case). An address (position in memory) is assigned to a, as to any other variable being declared, of course.

After that, expression &a is evaluated to initialize the variable (also a, but this is not relevant) just declared. The type of &a is "pointer to pointer to any type", which is a special case of "pointer to any type", fully compatible with the type of a. Ergo, no compiler message.

Corollary: do not use void* if you want strong type checking. Anything can be converted to it. Just the opposite in the reverse direction, except for void* itself (it would be an unnecessary exception that a type was incompatible with itself).

Also, AFAIR this really comes from C.