Pointers and Memory Addresses in C++
Check every void* assignment when porting C code to C++. If the code relies on an implicit conversion to another pointer type, C++ rejects it; make the conversion explicit and review whether the target type is appropriate.
One Assignment, Two Language Rules
A pointer assignment that looks ordinary in C can stop compiling when the same code is moved to C++. The key difference is how the languages handle converting a generic void* to a pointer with a specific type. Before looking at the rule, predict what happens in C++ when a void* that points to a character is assigned to an int* without a cast.
What do you think happens?
In C++, is this assignment accepted without a cast: int* p = void_ptr; when void_ptr has type void*?
Reveal answer
No. In C++, assigning a void* to an int* requires an explicit conversion.
The fact that void* can point to an object of any type does not mean C++ implicitly converts it to every other pointer type.
Check the Conversion Before the Assignment
A void* is a generic pointer: it can point to an object of any type, but it does not carry information about the type of the object it points to. C permits a void* to be assigned to a pointer of another type without a cast. C++ does not permit that implicit conversion. So, when you encounter an assignment from void* in C++, first check whether the assignment includes an explicit conversion. If it does not, the assignment is rejected under this rule.
Predict the C++ Result
A character variable is pointed to by a void*. An int* is then assigned from that void* with no cast. Is the assignment accepted in C++?
- 1Identify the source type
The value being assigned has type void*.
- 2Identify the target type
The destination has type int*.
- 3Apply the C++ rule
The assignment asks C++ to convert void* to another pointer type implicitly, which is not allowed.
The assignment is rejected in C++. Adding an explicit conversion makes the conversion visible in the code; it does not by itself establish that the pointed-to memory is safe to use as an int.
When a Pointer Writes Past Its Object
Making a void* point at an object does not make the memory large enough for every other type. If that address is treated as a pointer to a larger type, a write through the converted pointer can reach bytes beyond the original object. For example, the source describes a character object and an int* assigned from the void* that points to it. A write through that int* can overwrite the character and nearby bytes that belong to something else. The available facts establish this possible overrun, but do not specify an exact number of bytes for it.
Handle malloc() Results Explicitly
malloc() returns a void* pointing to allocated memory. C allows that result to be assigned to a pointer of another type without a cast; C++ does not. When using malloc() in C++, cast its result to the intended pointer type. The source's practical guidance is to avoid malloc() in C++-only code. When moving C code into a C++ project, look for implicit void* conversions and make each conversion explicit so the intended target type is visible.
| Situation | C | C++ |
|---|---|---|
| Assign void* to another pointer type | Implicit assignment is allowed. | An explicit conversion is required. |
| Assign malloc() result to a typed pointer | No cast is required for the assignment. | Cast the result to the intended pointer type. |
| C++-only code | Not applicable. | The source advises avoiding malloc(). |
The language difference concerns the conversion from void* to a typed pointer.
Practice the Porting Check
A C file contains an assignment from a void* variable to a pointer of another type, with no cast. You are reviewing it for use in a C++ project. What does the C++ compiler do with that assignment, and what change does the source recommend?
Hints
- Identify the source and destination pointer types.
- Apply the C++ rule for implicit conversion from void*.
- Consider what should be made explicit when porting the code.
Check every void* assignment when porting C code to C++. If the code relies on an implicit conversion to another pointer type, C++ rejects it; make the conversion explicit and review whether the target type is appropriate.
Key Takeaways
- C allows void* to be assigned to another pointer type without a cast; C++ does not allow that implicit conversion.
- In C++, an assignment from void* to a different pointer type needs an explicit conversion.
- Treating memory for a smaller object as a larger type can make a write reach nearby bytes; the exact overwrite extent is not specified here.
- In C++, cast a
malloc()result to the intended pointer type, and avoidmalloc()in C++-only code as the source advises. - When porting C code to C++, search for implicit void* conversions and review each target type.