Considering the following code (and the fact that VirtualAlloc() returns a void*):
BYTE* pbNext = reinterpret_cast<BYTE*>(     VirtualAlloc(NULL, cbAlloc, MEM_COMMIT, PAGE_READWRITE));   why is reinterpret_cast chosen instead of static_cast?
I used to think that reinterpret_cast is OK for e.g. casting pointers to and from integer types (like e.g. DWORD_PTR), but to cast from a void* to a BYTE*, isn't static_cast OK?
Are there any (subtle?) differences in this particular case, or are they just both valid pointer casts?
Does the C++ standard have a preference for this case, suggesting a way instead of the other?
Pointer is merely a memory address. With typecasting, any type with enough size to hold the memory address can work like a pointer.
In plain C you can cast any pointer type to any other pointer type.
padd = (Addition*) &d; Unrestricted explicit type-casting allows to convert any pointer into any other pointer type, independently of the types they point to. The subsequent call to member result will produce either a run-time error or some other unexpected results.
For convertible pointers to fundamental types both casts have the same meaning; so you are correct that static_cast is okay.
When converting between some pointer types, it's possible that the specific memory address held in the pointer needs to change.
That's where the two casts differ.  static_cast will make the appropriate adjustment.  reinterpret_cast will not.
For that reason, it's a good general rule to static_cast between pointer types unless you know that reinterpret_cast is desired.  
You should static_cast. Use static_cast in cases where you're undoing an implicit conversion.
In this particular case, however, there is no difference because you're converting from void*. But in general, reinterpret_casting between two object pointers is defined to be (§5.2.10/7):
An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue
vof type “pointer toT1” is converted to the type “pointer to cvT2”, the result isstatic_cast<cv T2*>(static_cast<cv void*>(v))if bothT1andT2are standard-layout types and the alignment requirements ofT2are no stricter than those ofT1, or if either type isvoid. Converting a prvalue of type “pointer toT1” to the type “pointer toT2” (whereT1andT2are object types and where the alignment requirements ofT2are no stricter than those ofT1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.
Emphasis mine. Since T1 for you is already void*, the cast to void* in reinterpret_cast does nothing. This is not true in general, which is what Drew Dormann is saying:
#include <iostream>  template <typename T> void print_pointer(const volatile T* ptr) {     // this is needed by oversight in the standard     std::cout << static_cast<void*>(const_cast<T*>(ptr)) << std::endl; }  struct base_a {}; struct base_b {}; struct derived : base_a, base_b {};  int main() {     derived d;      base_b* b = &d; // implicit cast      // undo implicit cast with static_cast     derived* x = static_cast<derived*>(b);      // reinterpret the value with reinterpret_cast     derived* y = reinterpret_cast<derived*>(b);      print_pointer(&d);     print_pointer(x);     print_pointer(y); }   Output:
00CBFD5B
00CBFD5B
00CBFD5C
(Note that because y doesn't actually point to a derived, using it is undefined behavior.)
Here, reinterpret_cast comes up with a different value because it goes through void*. This is why you should use static_cast when you can, and reinterpret_cast when you have to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With