Reputation: 204
Why does the following code behave differently on iPhone simulator and device? Im running the simulator on an intel macbook pro and the device is an iPhone 5 (model MD297KS/A).
Code:
uint8_t original = 23;
uint8_t * pointerToOriginal = &original;
uint32_t * casted = (uint32_t *)pointerToOriginal;
printf("original: %u\ncasted: %u\n", original, *casted);
Output when ran on simulator:
original: 23
casted: 23
Output when ran on device:
original: 23
casted: 2755278871
I assumed the cast would result in garbage data being included in the casted integer so the device output makes sense to me, but why is the integer unaffected by the extra data introduced in the cast on simulator?
Upvotes: 2
Views: 134
Reputation: 2539
First of all your code will lead to undefined behavior. But to make things clear i will try to explain what is going on.
original
is stored on stack. So when you take pointer to original
you will get pointer to region with length 8bit in stack memory (this information available only for compiler). Like so:
byte 0 byte 1 byte 2 byte 3
[00010111][????????][????????][????????]
Lets say that stack starts from address 0.
So pointerToOriginal
will point to byte at address 0. Compiler know that pointerToOriginal
points to 8bit value(because of it's type). So when unreferencing it will read exactly 1 byte starting from address 0.
But when converting uint8_t*
to uint32_t*
you actually force compiler to read 4 bytes instead of 1. So you will end up with reading 4 bytes 3 of which going to be junk.
On the simulator looks like memory region is filled with zero. So stack will looks like so:
byte 0 byte 1 byte 2 byte 3
[00010111][00000000][00000000][00000000]
and when You dereferencing casted
you will get 23 back. But on real machine it will contain only junk.
Illustration above not explaining one more advanced stuff - Big and Little Endian.
Upvotes: 2
Reputation: 18009
From the C11 standard "6.3.2.3-7":
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. ...
From the C11 standard "J.2":
The behavior is undefined in the following circumstances: ...
- Conversion between two pointer types produces a result that is incorrectly aligned (6.3.2.3).
Emphasis mine
Upvotes: 5