quad16
quad16

Reputation: 204

Why does this uint32_t cast behave differently on iPhone simulator and iPhone device?

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

Answers (2)

j2ko
j2ko

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

sergej
sergej

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

Related Questions