I was looking at https://en.cppreference.com/w/cpp/language/reinterpret_cast and I noticed that it specifies the legal types we can always cast to:
byte*
char*
unsigned char*
But I did not see void*
in the list. Is this an oversight? My use case requires a reinterpret_cast
because I'm casting from an int**
to a void*
. And I will eventually cast from the void*
back to an int**
.
The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function.
A void pointer can hold address of any type and can be typecasted to any type.
void *p = malloc(n * sizeof(int)); int *q = (int *) p; int *q = p; // implicit type cast from void * to int * is allowed! int *q = malloc(n * sizeof(int)); // same as int *q = p.
Reinterpret casts are only available in C++ and are the least safe form of cast, allowing the reinterpretation of the underlying bits of a value into another type. It should not be used to cast down a class hierarchy or to remove the const or volatile qualifiers.
Those types are exempt from strict aliasing rules. It does not mean they are the only type you can use with reinterpret_cast
. In the case of casting an object pointer to another object pointer type, failing to meet the requirements of strict aliasing rules means you cannot safely dereference the result. But you can still cast the resulting pointer back to the original type safely, and use the result as-if it was the original pointer.
The relevant section from cppreference on reinterpret_cast
:
(Any object pointer type
T1*
can be converted to another object pointer type cvT2*
. This is exactly equivalent tostatic_cast<cv T2*>(static_cast<cv void*>(expression))
(which implies that ifT2
's alignment requirement is not stricter thanT1
's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules)
When casting back to the original type, AliasedType
and DynamicType
are the same, so they are similar, which is the first case listed by the aliasing rules where it is legal to dereference the result of reinterpret_cast
:
Whenever an attempt is made to read or modify the stored value of an object of type
DynamicType
through a glvalue of typeAliasedType
, the behavior is undefined unless one of the following is true:
AliasedType
andDynamicType
are similar.AliasedType
is the (possibly cv-qualified)signed
orunsigned
variant ofDynamicType
.AliasedType
isstd::byte
, (since C++17)char
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes.
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