This is actually very annoying, but not so unexpected for those of us who bought pre-x86 in the world :-)
The only reason that comes to mind (and this is pure speculation) is that the compiler โcorrectsโ your code to make sure that the data types are correctly aligned and that sizeof/alignof cause problems. I seem to remember that the ARM6 architecture loosened some rules for some data types, but never got a good look at it, because it was decided to go with a different processor.
(Update: this is actually controlled by setting the register (maybe this is software), so I believe that even modern processors can still complain about inconsistencies).
The first thing I would like to do is look at the generated assembly to see if the compiler complements your short one, to align the next (actual) data type (which would be impressive) or (more likely) fill the actual data type before writing it .
Secondly, find out what the actual alignment requirements are for the Cortex A8, which, in my opinion, is the core used in the iPhone4.
Two possible solutions:
1 / You may have to superimpose each type into a char array and pass characters one at a time - this, I hope, will avoid alignment problems, but it can have an impact on performance. Using memcpy probably be better, since it would no doubt be encoded to use the underlying CPU already (for example, transmit four byte fragments, where possible, with single-byte fragments at the beginning and end).
2 / For those types of data that do not need to be set immediately after short , after that short add enough addition to make sure that they are correctly aligned. For example, something like:
tmp += sizeof(unsigned short); tmp = (tmp + sizeof(T)) % alignof(T);
which should push tmp to the next correctly aligned location before trying to save the value.
You will need to do the same thing as reading later (I assume that the short indicates the stored data so that you can indicate what type of data it is).
Putting the final decision from the OP in the answer for completeness (so people don't check the comments):
First, the assembly (on Xcode, Run menu > Debugger Display > Source and Disassembly ) shows that the STMIA command STMIA used to process 8 bytes of data (i.e. long long ) instead of the STR instruction.
Further, in section โA3.2.1โ Unallocated data access โin theโ ARM Architecture ARMv7-A Reference Guide โ(architecture corresponding to Cortex A8) it is said that STMIA does not support unaudited data access, and STR does (depending on certain registry settings).
So the problem was long long size and misalignment.
As for the solution, one - char -at-a-time works as a starter.