我通过将文件映射到内存并通过 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
(调试)中,最里面的 block 作为以下程序集发出,它正常工作:
ldr r1, [r0, #24]
ldr r2, [r0, #20]
在 -O2
中,编译器意识到这些字段是相邻的并生成此程序集:
ldrdeq r2, r3, [r0, #20]
不幸的是,LDRD
总是会产生对齐错误(根据规范和实践)。所以我需要一种方法来有效地通知编译器这个问题。理想情况下,这可以通过结构上的属性来完成。这也有可能是编译器或 ARM 后端的错误,但我会给他们带来疑问。
我正在使用针对 iPhone 的 armv7 的 Xcode 4.2 (clang 3.0) 进行编译。
最佳答案
问题不在于结构的字段没有所需的对齐方式,而是您将任意指针强制转换为指向您的结构的指针,而您正在强制转换的指针没有需要对齐结构。严格来说,这是未定义的行为。
相反,memcpy
您的数据从源缓冲区到您的结构。 memcpy
速度很快,并且保证可以处理您向它提出的任何对齐方式。
关于c - 指示对 Clang 的未对齐访问以实现 ARM 兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9185811/