The following two pieces of code works fine when optimization level is -o0. But, when the optimization level is anything other than -o0, the first code crashes at some point, but the seconds does not crash. could you please explain why?
1.
unsigned char* _pos = ...;
double result;
*((int*)&result) = *((int*)_pos;
2.
unsigned char* _pos = ...;
double result;
int* curPos = (int*)_pos;
int* resultPos = (int*)&result;
*resultPos = *curPos;
EDIT: By the way, this code is in an inlined function. When the function is not inlined, there in no crash even with optimizations.
The code here actually yields several problems at once. First, as it was said before, the code violates the aliasing rules and thus the result is undefined per standard. So, strictly speaking, compiler can do bunch of stuff while optimizing (this is actually your case when the code mentioned above is inlined).
Second (and I believe this is the actual problem here) - casting char* to int* will increase the assumed alignment of the pointer. According to your platform ABI, char can be 1 byte aligned, but int - at least 4 (double is 8 byte aligned, btw). The system can tolerate the unaligned loads, but not always, e.g. on arm/darwin it can tolerate 4 byte unaligned loads, but not 8. The latter case can happen when compiler would decide to merge two consecutive loads / stored into 1. Since you bumped the actual alignment of the pointer compiler might deduce that everything is suitable aligned and generate such 8 byte loads.
So, in short - fix your code :) In this particular case memcpy / memmove will help you.
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