首先我们谈谈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吗?
一方面Intel CPU允许不对齐访问, 从另一只手我发现了这个: http://www.uclibc.org/docs/psABI-i386.pdf http://www.x86-64.org/documentation/abi.pdf 他们都提到了 4 字节整数的 4 字节对齐。
那么即使它编译并工作正常,它仍然是 UB 吗? 因为gcc认为“uint32_t *”指针的值指向 4字节对齐地址, 并毫不犹豫地在“f”函数中使用“SSE”?
gcc 维护者认为这样的代码是“未定义的代码”: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66194
编译和链接正常意味着什么,未定义的行为发生在运行时。就 C 标准而言,代码可能会也可能不会调用 UB。
6.3.2.3/7:
指向对象类型的指针可以转换为指向 不同的对象类型。如果结果指针不正确 与引用类型对齐,行为未定义。
术语“正确对齐”取决于 CPU 架构。如果你的CPU没有对齐限制,uint32_t指针就被认为是正确对齐的,那么你就没有UB了。
如果CPU允许未对齐的访问,但它会导致代码效率较低,那么你也将没有UB。
但是如果CPU不支持未对齐访问,那么代码就是UB。
x86 和 x64 指令集都允许未对齐访问,而不会导致未定义的行为(SIMD 扩展指令集除外)。
x86/x64 中的代码存在的问题是,由于别名冲突,它会调用未定义的行为。由于您已经在使用
gcc
扩展,您可以使用 -fno-strict-aliasing
禁用别名规则。
两者都是。可能 gcc 维护者发现了不遵守某些标准的实现,这就是它被定义和未定义的原因。维护者或维护者怎么样,不知道它是如何正确的?对我来说,这个问题非常具体,但是,我发现其中有些冗余。这里无法在稳定版Xcode上打开故事板作者使用了他或她的语言。我通过此链接只找到了 70 多个问题https://stackoverflow.com/search?tab=votes&q=ru.stackoverflow.com&searchOn=3 虽然有 80 多个 https://stackoverflow.com/search?q=PGPPublicKeyRing 我在哪里读到 JWT 和 OAuth 身份验证之间的主要区别是什么? 来自印度人,因为它很容易理解。我在印度永远找不到它,反之亦然。此外,他们还有哈布拉哈布尔。但如果你害羞或被禁止怎么办?或者,如果我在这里禁止,那么显然所有答案和问题都是供作者或女作者审查的。底线:显然这里的问题应该具有语言属性而不是域。