C++ was based on C and retains a great deal of the functionality. C++ does not retain complete source-level compatibility with C.
There are a few anomalies for C++ programmers trying to write C code, and C programmers trying to compile with a C++ compiler.
Can you implicitly assign from a void* type to any other type in C++?
No, in C++, you cannot implicitly assign from a void* to any other pointer type. The C++ language is more strict than C when it comes to type safety, and this is evident in the handling of void pointers. In C, a void* pointer can be implicitly cast to any other pointer type. However, in C++, an explicit cast is required to convert a void* to another pointer type.
Here is an example illustrating this difference:
// In C, this is allowed.
// In C++, this would generate a compile error.
i_ptr = v_ptr;
// In both C and C++, this is allowed.
i_ptr = (int*)v_ptr;
In the above example, the assignment i_ptr = v_ptr; would be acceptable in C, but in C++, it would generate a compile-time error. To make this assignment in C++, an explicit cast is required, as in i_ptr = (int*)v_ptr;.
This stricter requirement in C++ helps to prevent errors that could occur due to incorrect assumptions about the type of data being pointed to by a void pointer. It reflects the overall philosophy of C++ to provide stronger type checking than C, to reduce the possibility of programmer errors.
Note: Even though C++ allows you to cast a void* to any other pointer type, it's generally a good practice to avoid this unless absolutely necessary. The reason is that such a cast bypasses the type system, possibly leading to subtle bugs. Whenever possible, it's better to use safe and well-defined conversions and casts.
You cannot implicitly assign from a void* to any other type. For instance, the following is perfectly valid in C (in fact, it's arguably the preferable way of doing it in C)
but it will not compile in C++.
The explanation from Bjarne Stroustrup himself is that this is not type safe.
What this means is that you can have a void* that points to anything at all, and if you then assign the address stored in that void* to another pointer of a different type, there is not any warning at all about it.
Consider the following:
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 5;
When you assign *double_ptr the value 5, it's writing 8 bytes of memory, but the integer variable an_int is only 4 bytes. Forcing a cast from a void pointer makes the programmer pay attention to these things.