I ran into this problem while trying to traverse a byte array where the data length in bytes is known at run-time. https://godbolt.org/z/-vgEk_
#include <cstdint>
void f()
{
uint8_t* array = new uint8_t[4*10];
// cannot convert 'unsigned char*' to 'unsigned int*' in initialization
uint32_t* fourByteIterator1 = array;
// invalid static_cast from 'unsigned char*' to 'unsigned int*'
uint32_t* fourByteIterator2 = static_cast<uint32_t*>(array);
// no problems
uint32_t* fourByteIterator3 = (uint32_t*)array;
// no problems
void* intermediate = static_cast<void*>(array);
uint32_t* fourByteIterator4 = static_cast<uint32_t*>(p);
// no problems
uint32_t* fourByteIterator5 = reinterpret_cast<uint32_t*>(array);
}
Why does static_cast fail in the second conversion? And then, why is it valid to cast from void* to uint32_t* if that is not valid when directly casting to uint32_t* using static_cast? Is statically casting a pointer type twice via void* the same as a direct reinterpret cast?
uint32_t* fourByteIterator1 = (whatever_cast)array;
Accessing fourByteIterator1 is Undefined Behavior, no matter how you manage to get the cast working. Accessing the memory obtained from new uint8_t[4*10]; as objects of type uint32_t is a violation of the strict aliasing rules.
As for why some methods of casts work and other don't ... well... that's what the standard says. And the rules are like they are to protect you from making mistakes. The fact that you cannot directly cast between them except with reinterprect_cast is a very good indication that you probably shouldn't.
The cast via void* works because any pointer type can be casted to void * and if you cast back to the original pointer type you are guaranteed to get the original pointer back. So that's why casting to and from void * is "more allowed" then other pointer types. But that's not what you are doing. You are not casting back to the original pointer type.
Is statically casting a pointer type twice via void* the same as a direct reinterpret cast?
Yes.
In conclusion: don't do that. It is Undefined Behavior.
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