Я анализирую формат файла, отображая файл в память и получая к нему доступ через определения структуры C.Формат файла использует упакованные структуры, поэтому я не могу гарантировать, что поле будет выровнено по границе слова.
Синтаксический анализ работает очень хорошо, к сожалению, в некоторых случаях оптимизатор может нанести ущерб.В частности, при компиляции для armv7 существуют определенные инструкции загрузки, которые требуют выравнивания слов, а другие - нет.Рассмотрим этот фрагмент:
#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);
...
}
}
В -O0
(отладка) самый внутренний блок выводится как следующая сборка, которая работает правильно:
ldr r1, [r0, #24]
ldr r2, [r0, #20]
В -O2
однако компиляторпонимает, что эти поля являются смежными и генерирует эту сборку:
ldrdeq r2, r3, [r0, #20]
К сожалению, LDRD
всегда генерирует ошибку выравнивания (по спецификации и на практике).Поэтому мне нужен способ эффективно сообщить компилятору об этой проблеме.В идеале это можно сделать с помощью атрибута структуры.Также возможно, что это ошибка компилятора или бэкэнда ARM, но я дам им преимущество сомнения.
Я компилирую с Xcode 4.2 (clang 3.0), ориентируясь на armv7 для iPhone.