我有以下测试程序:
#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 为 arm-linux-gnueabihf 编译时,编译器怀疑指针访问可能未对齐,在程序集输出中注释加载和存储,例如:
ldr r0, [r0, #0] @ unaligned
如果我使用 -mno-unaligned-access
编译,编译器根本不会发出直接加载和存储,而是调用库 memcpy
。但实际上,这种情况下的指针永远不应该未对齐。这是 gcc 中的一个忽略,还是我弄错了?
最佳答案
在 C 编译器中,没有什么比 int
值的加载和存储更好的优化了,这在设计上是机器的自然大小。
将函数写成
int q(int *p) {
return *p += 12;
}
这避免了对库例程的两次调用,否则您指望优化器将其内联并减少为简单的加载和存储,并表达了就地修改整数值参数并返回结果的意图。
使用 memcpy
来分配整数会混淆意图。
如果这个问题是将一个较大的问题简化为最小的混淆示例的结果,那么我的实现可能不会直接提供帮助。但即使 p
的类型是 some_complex_struct *
而不是 int *
,建议仍然适用。赋值运算符有效。在有意义的地方优先使用它而不是 memcpy
。
关于c - GCC 认为 int 指针在 ARM 上未对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16191323/