I'm parsing a file format by mapping a file to memory and accessing it through C struct definitions. The file format uses packed structures, so I cannot guarantee that a field will align to a word boundary.
The parsing works just fine, unfortunately in certain cases the optimizer may wreak havoc. In particular, compiling for armv7 there are certain load instructions that require word alignment and others that do not. Consider this snippet:
#define PACKED __attribute__((packed))
typedef struct PACKED _Box_mvhd {
union {
struct {
int32_t creation_time;
int32_t modification_time;
int32_t time_scale;
int32_t duration;
...
} v0;
} data;
} Box_mvhd;
Container mvhd = find_single_box(&moov, 'mvhd');
if (mvhd.boxStart) {
Box_mvhd *mvhdBox = mvhd.mvhd;
if (0 == mvhdBox.box.version) {
uint32_t ts = ntohl(mvhdBox->data.v0.time_scale);
uint32_t dur = ntohl(mvhdBox->data.v0.duration);
...
}
}
In -O0
(debugging) the innermost block is emitted as the following assembly, which works properly:
ldr r1, [r0, #24]
ldr r2, [r0, #20]
In -O2
however the compiler realizes these fields are adjacent and generates this assembly:
ldrdeq r2, r3, [r0, #20]
Unfortunately LDRD
always generates an alignment fault (by spec and in practice). So I need a way to inform the compiler of this issue effectively. Ideally this could be done with an attribute on the struct. It's also possible that this is a bug with the compiler or ARM backend, but I'll give them the benefit of the doubt.
I'm compiling with Xcode 4.2 (clang 3.0) targeting armv7 for iPhone.
The issue isn't that the fields of the struct don't have the required alignment, it's that you're casting an arbitrary pointer to a pointer to your struct, and the pointer you're casting doesn't have the required alignment of the struct. Strictly speaking this is undefined behavior.
Instead, memcpy
your data from the source buffer to your struct. memcpy
is fast, and guaranteed to handle whatever alignment you throw at it.
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