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_cast
ing 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 v
of type “pointer to T1
” is converted to the type “pointer to cv T2
”, the result is static_cast<cv T2*>(static_cast<cv void*>(v))
if both T1
and T2
are standard-layout types and the alignment requirements of T2
are no stricter than those of T1
, or if either type is void
. Converting a prvalue of type “pointer to T1
” to the type “pointer to T2
” (where T1
and T2
are object types and where the alignment requirements of T2
are no stricter than those of T1
) 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.