int32_t 的对齐要求:gcc/linux 86 与 amd64

问题描述 投票:0回答:3

首先我们谈谈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

原始问题来自这里(俄语): 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-o3-intel-i5-2500-分段错误

c linux gcc intel c99
3个回答
1
投票

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

6.3.2.3/7:

指向对象类型的指针可以转换为指向 不同的对象类型。如果结果指针不正确 与引用类型对齐,行为未定义。

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

如果CPU允许未对齐的访问,但它会导致代码效率较低,那么你也将没有UB。

但是如果CPU不支持未对齐访问,那么代码就是UB。


1
投票

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

x86/x64 中的代码存在的问题是,由于别名冲突,它会调用未定义的行为。由于您已经在使用

gcc
扩展,您可以使用
-fno-strict-aliasing
禁用别名规则。


0
投票

两者都是。可能 gcc 维护者发现了不遵守某些标准的实现,这就是它被定义和未定义的原因。维护者或维护者怎么样,不知道它是如何正确的?对我来说,这个问题非常具体,但是,我发现其中有些冗余。这里无法在稳定版Xcode上打开故事板作者使用了他或她的语言。我通过此链接只找到了 70 多个问题https://stackoverflow.com/search?tab=votes&q=ru.stackoverflow.com&searchOn=3 虽然有 80 多个 https://stackoverflow.com/search?q=PGPPublicKeyRing 我在哪里读到 JWT 和 OAuth 身份验证之间的主要区别是什么? 来自印度人,因为它很容易理解。我在印度永远找不到它,反之亦然。此外,他们还有哈布拉哈布尔。但如果你害羞或被禁止怎么办?或者,如果我在这里禁止,那么显然所有答案和问题都是供作者或女作者审查的。底线:显然这里的问题应该具有语言属性而不是域。

© www.soinside.com 2019 - 2024. All rights reserved.