gpt4 book ai didi

c - 只要您永远不取消引用它,持有未对齐的指针是否定义明确?

转载 作者:太空狗 更新时间:2023-10-29 16:21:09 26 4
gpt4 key购买 nike

我有一些 C 代码可以解析来自网络的打包/未填充二进制数据。

这段代码在 Intel/x86 下运行良好,但当我在 ARM 下编译它时,它经常会崩溃。

正如您可能已经猜到的那样,罪魁祸首是未对齐的指针——特别是,解析代码会做这样有问题的事情:

uint8_t buf[2048];
[... code to read some data into buf...]
int32_t nextWord = *((int32_t *) &buf[5]); // misaligned access -- can crash under ARM!

...这显然不会在 ARM 领域中运行,所以我将其修改为看起来更像这样:

uint8_t buf[2048];
[... code to read some data into buf...]
int32_t * pNextWord = (int32_t *) &buf[5];
int32 nextWord;
memcpy(&nextWord, pNextWord, sizeof(nextWord)); // slower but ARM-safe

我的问题(从语言律师的角度来看)是:我的“ARM 固定”方法是否在 C 语言规则下得到了明确定义?

我担心的是,即使我从未真正直接取消引用它,即使只有一个未对齐的 int32_t 指针也可能足以调用未定义的行为。 (如果我的担心是正确的,我想我可以通过将 pNextWord 的类型从 (const int32_t *) 更改为 (const char *)< 来解决这个问题,但我宁愿不这样做,除非确实有必要这样做,因为这意味着手动执行一些指针步长算术)

最佳答案

不,新代码仍然有未定义的行为。 C11 6.3.2.3p7 :

  1. A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned 68) for the referenced type, the behavior is undefined. [...]

它没有说明任何关于取消引用指针的内容 - 即使转换具有未定义的行为。


事实上,您认为是 ARM 安全的修改后的代码可能甚至不是 Intel 安全的。已知编译器会为 Intel that can crash on unaligned access 生成代码.虽然不是在链接的情况下,但可能只是聪明的编译器可以将转换作为地址确实对齐的证明,并为 memcpy 使用专门的代码。


撇开对齐不谈,您的第一个摘录也存在严重的混叠违规问题。 C11 6.5p7 :

  1. An object shall have its stored value accessed only by an lvalue expression that has one of the following types:88)
    • a type compatible with the effective type of the object,
    • a qualified version of a type compatible with the effective type of the object,
    • a type that is the signed or unsigned type corresponding to the effective type of the object,
    • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
    • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
    • a character type.

由于数组 buf[2048] 是静态类型,每个元素都是 char,因此元素的有效类型是 字符;您可以作为字符访问数组的内容,而不是int32_t

即,甚至

int32_t nextWord = *((int32_t *) &buf[_Alignof(int32_t)]);

有未定义的行为。

关于c - 只要您永远不取消引用它,持有未对齐的指针是否定义明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51203570/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com