c - 指示对 Clang 的未对齐访问以实现 ARM 兼容性

标签 c gcc arm clang

我通过将文件映射到内存并通过 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/

相关文章:

Docker-entrypoint.sh 为带有 golang 的 ARM 镜像生成 "not found"

c++ - 测量可执行文件的数据和指令缓存的大小

c++ - OS X 上的 LLVM 与 clang

c++ - 在服务器端禁用 OpenSSL 的弱密码

c - OpenGL (GLFW) 在 macOS Mojave 上不显示图像

c++ - 从参数的返回类型推断类型

assembly - Neoverse N1 中 lsl >4 的 add 管道

ARM : What's the difference between APCS and AAPCS ABI?

c - Fwrite/Fread 动态声明的结构 **

opencv - 编译 OpenCV 时出错, fatal error : stdlib. h: No such file or directory