I'm trying to understand the differences between C and C++ with regards to void pointers. the following compiles in C but not C++ (all compilations done with gcc/g++ -ansi -pedantic -Wall):
int* p = malloc(sizeof(int));
Because malloc
returns void*
, which C++ doesn't allow to assign to int*
while C does allow that.
However, here:
void foo(void* vptr)
{
}
int main()
{
int* p = (int*) malloc(sizeof(int));
foo(p);
return 0;
}
Both C++ and C compile it with no complains. Why?
K&R2 say:
Any pointer to an object may be converted to type
void *
without loss of information. If the result is converted back to the original pointer type, the original pointer is recovered.
And this pretty sums all there is about void*
conversions in C. What does C++ standard dictate?
In C, pointer conversions to and from
void*
were always implicit.In C++, conversions from
T*
tovoid*
are implicit, butvoid*
to anything else requires a cast.It is useful to understand that pointer type conversions don't really require execution of extra CPU instructions. They are analysed during the compile time to understand the intensions of the developer.
void *
is an opaque pointer. All it says that the type of pointed object is unknown. C is weakly typed. It allows direct conversion between (void *
) and any (T*
) implicitly. C++ is strongly typed. A conversion from (void *
) to (T*
) wouldn't really make good case for a strongly typed language. But C++ had to stay backwards compatible with C, hence it had to allow such conversions. The guiding principle then is: explicit is better than implicit. Hence if you wish to convert an (void*
) to some specific (T*
) pointer, you need to explicitly write that in code. Conversion from (T*
) to (void*
) doesn't require explicit conversion since there is nothing much one can do on a (void*) pointer directly (one can call free() though). Hence (T*
) to (void*
) conversion is pretty much safe.C++ is more strongly-typed than C. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion. The new operator in C++ is a type-safe way to allocate memory on heap, without an explicit cast.