Both functions are valid C++ and have well-defined behavior (modifying the data
member of the A
object created in main
) in C++11 and later.
You are allowed to obtain a pointer to non-const
from a pointer to const
object type either directly with const_cast
or indirectly with static_cast
going through void*
as you are doing in foo
. That in itself is not a problem:
The cast to void*
is possible because &a
is a pointer to const A*
which is not (top-level) cv-qualified. The cast from void*
to A**
is possible because void*
can be cast to any object pointer type. Dereferencing the result is accessing the const A*
object through a pointer to A*
, but that is ok because the types are similar. (The last part seems to have been an aliasing rule violation prior to C++11, making this undefined behavior.)
However, modifying a const
qualified object through a pointer to non-const
obtained in such a way causes undefined behavior.
Since the object A a;
that you are passing to the function is not const
qualified, there is no problem.
But I think it is obvious why using such functions is dangerous. Changing the declaration A a;
to const A a;
will still compile because there is no type mismatch, but will have undefined behavior.
Both functions do exactly the same thing in all situations, as far as I can tell.