Imagine the following situation:
An array of 4 elements of type uint8_t is given that represent 32 bit integer, byte by byte. The goal is to address the whole array as a 32 bit integer.
int main( void )
{
uint8_t array[4] = { 0, 0, 0, 12 };
uint32_t * ptr = ( uint32_t * )array;
printf("%d", *ptr);
return 0;
}
Forget about endianess for now, it is not relevant to the question (I do not think).
Now the C standard says that casting a pointer to a type with more strict alignment is undefined behavior.
Some examples of compliant and non-compliant code are given here: https://wiki.sei.cmu.edu/confluence/display/c/EXP36-C.+Do+not+cast+pointers+into+more+strictly+aligned+pointer+types
The code above compiles and gives expected result on latest GCC and IAR compilers I've tried.
The question is whether this code is safe in general?
I imagine the following situation on the architecture where integer type is self-aligned. My logic is that since array will inherit the alignment specification of its most strict type - char it can be placed anywhere in memory. For example:
Memory | Value | integer can start here
....
0x20 | | yes
0x21 | 0 | no <- array begins, uint32_t ptr
0x22 | 0 | no
0x23 | 0 | no
0x24 | 12 | yes
....
In this scenario if we dereference a uint32_t pointer we may potentially crash on some architectures.
Did I miss something here? Obviously this code works on major compilers and I would imagine that cases where it fails are very specific, more related to legacy architectures and compilers. Nevertheless, is such code safe and portable as according to C standard?
If I made incorrect assumptions or interpreted something incorrectly, please let me know.