How is void *a = &a legal?

C++

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

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 - C++

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 - C++

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2681063View Question on Stackoverflow
Solution 1 - C++Matthieu M.View Answer on Stackoverflow
Solution 2 - C++StasikView Answer on Stackoverflow
Solution 3 - C++Mario RossiView Answer on Stackoverflow