【发布时间】:2013-04-17 23:09:15
【问题描述】:
我有以下测试程序:
#include <string.h>
int q(int *p) {
int x;
memcpy(&x,p,sizeof(int));
x+=12;
memcpy(p,&x,sizeof(int));
return p[0];
}
当我使用 GCC 4.7.2 for arm-linux-gnueabihf 编译它时,编译器怀疑指针访问可能未对齐,在程序集输出中注释加载和存储,例如:
ldr r0, [r0, #0] @ unaligned
如果我使用-mno-unaligned-access 编译,编译器根本不会发出直接加载和存储,而是调用库memcpy。但实际上,这种情况下的指针永远不应该是未对齐的。这是 gcc 中的一个忽略,还是我弄错了?
【问题讨论】:
-
请发布编译后代码的完整反汇编。
-
int q(int *restrict p) { p[0]+=12; return p[0];}做得更好。mov r3,r0,ldr r0,[r0],add r0,r0,#12,str r0,[r3],blx。你为什么要编码这个?确实应该对齐。正如其他人所指出的,您将它与memcpy()混淆了。至少,x = p[0];似乎是半理智的。你为什么使用memcpy()作为作业?下一个人会出现并宣布*p是字节交换版本。也许更大的问题会有所帮助? -
使用
memcpy的要点是要兼容严格的别名规则。给定的int *指针可能派生自指向另一种类型的指针。 -
@Juho 嗯,这正是
gcc生成memcpy的原因,因为如果int*p是伪装的char*p,那么它可能根本没有对齐。所以我什至不确定编译器是否可以决定(除了整个程序分析)int*p是对齐的。考虑到你的动机gcc是对的。 -
如果一个指针被强制转换为
int*,这是对编译器的一个承诺,即结果是正确对齐的。编译器不需要支持通过int*进行非对齐访问,例如,gcc 已经为此提供了打包结构。
标签: c gcc arm memory-alignment