alignment要求为int32_t:gcc / linux 86 vs amd64

首先我们谈论gcc / linux(x86,amd64)和c99。

这里是代码:

#include <stdint.h> void f(void *p) { uint32_t *num = p; *num = 17; } int main() { char buf[8] __attribute__ ((aligned (8))); f(&buf[3]); } 

问题是UB?

从一方面英特尔CPU允许不公正的访问,另一方面我发现这个: http : //www.uclibc.org/docs/psABI-i386.pdf http://www.x86-64.org/documentation/abi.pdf并且他们都提到4字节alignment为4字节整数。

所以即使编译和工作正常,它仍然是UB? 因为gcc认为“uint32_t *”指针的值指向4字节alignment的地址,并且在“f”函数中使用例如“SSE”而毫不犹豫?

gcc维护者认为这样的代码是“未定义代码”: https : //gcc.gnu.org/bugzilla/show_bug.cgi?id = 66194

原来的问题是从这里(俄语): https : //ru.stackoverflow.com/questions/268888/%D0%9E%D0%BF%D1%8F%D1%82%D1%8C-%D0%BE% D0%B1-%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8-GCC -03-英特尔i5-2500分割故障

编译并链接好就意味着什么,运行时发生未定义的行为。 就C标准而言,代码可能会或可能不会调用UB。

6.3.2.3/7:

指向对象类型的指针可能会转换为指向不同对象类型的指针。 如果生成的指针未正确对齐引用类型,则行为是不确定的。

术语“正确对齐”取决于CPU架构。 如果你的CPU没有对齐限制,uint32_t指针被认为是正确对齐的,那么你将没有UB。

如果CPU允许访问不对齐,但是会导致代码效率不高,那么你也不会有UB。

但是如果CPU不支持错位访问,那么代码是UB。

除了SIMD扩展指令集之外,x86和x64指令集都允许未对齐的访问,而不会导致未定义的行为。

在x86 / x64中的代码的问题是它调用未定义的行为,因为混叠违反。 由于您已经在使用gcc扩展,因此可以使用-fno-strict-aliasing禁用别名规则。