gpt4 book ai didi

c++ - 通过 reinterpret_cast 的非对齐访问

转载 作者:IT老高 更新时间:2023-10-28 22:04:46 25 4
gpt4 key购买 nike

我正在进行讨论,试图通过 reinterpret_cast 确定 C++ 中是否允许未对齐访问。 .我认为不是,但我很难找到标准的正确部分来证实或反驳这一点。我一直在看 C++11,但如果它更清楚,我会使用另一个版本。

未对齐的访问在 C11 中未定义。 the C11 standard的相关部分(§ 6.3.2.3,第 7 段):

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 for the referenced type, the behavior is undefined.

由于未对齐访问的行为是未定义的,一些编译器(至少是 GCC)认为这意味着可以生成需要对齐数据的指令。大多数情况下,代码仍然适用于未对齐的数据,因为如今大多数 x86 和 ARM 指令都适用于未对齐的数据,但有些则不然。特别是,一些 vector 指令不能,这意味着随着编译器更好地生成优化指令,适用于旧版本编译器的代码可能不适用于新版本。当然,有些架构 (like MIPS) 对未对齐的数据表现不佳。

C++11当然,更复杂。 § 5.2.10,第 7 段说:

An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.

请注意,最后一个词是“未指定”,而不是“未定义”。 § 1.3.25 将“未指定行为”定义为:

behavior, for a well-formed program construct and correct data, that depends on the implementation

[Note: The implementation is not required to document which behavior occurs. The range of possible behaviors is usually delineated by this International Standard. — end note]

除非我遗漏了什么,否则该标准实际上并没有描述在这种情况下可能的行为范围,这似乎向我表明,一种非常合理的行为是为 C 实现的行为(至少由 GCC 实现) : 不支持。这意味着编译器可以自由地假设不发生未对齐访问并发出可能不适用于未对齐内存的指令,就像它对 C 所做的那样。

然而,我正在与之讨论这个问题的人有不同的解释。他们引用了第 1.9 节第 5 段:

A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input. However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).

由于不存在 undefined 行为,他们认为 C++ 编译器无权假设未对齐访问不会发生。

因此,通过 reinterpret_cast 进行的未对齐访问在 C++ 中安全吗?它在规范(任何版本)中的哪个位置说?

编辑:“访问”是指实际加载和存储。类似的东西

void unaligned_cp(void* a, void* b) {
*reinterpret_cast<volatile uint32_t*>(a) =
*reinterpret_cast<volatile uint32_t*>(b);
}

内存的分配方式实际上超出了我的范围(它适用于可以从任何地方使用数据调用的库),但是 malloc和堆栈上的数组都可能是候选者。我不想对内存的分配方式施加任何限制。

编辑 2:在答案中引用来源(,C++ 标准、部分和段落)。

最佳答案

看 3.11/1:

Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated.

关于究竟是什么构成了分配一个类型的对象,在评论中有一些争论。但是,我相信无论讨论如何解决,以下论点都有效:

*reinterpret_cast<uint32_t*>(a)例如。如果这个表达式不会导致 UB,那么(根据严格的别名规则)必须有一个 uint32_t 类型的对象。 (或 int32_t )在此语句之后的给定位置。对象是否已经存在,或者这个写入创建了它,都无关紧要。

根据上述标准引用,具有对齐要求的对象只能以正确对齐的状态存在。

因此,任何创建或写入未正确对齐的对象的尝试都会导致 UB。

关于c++ - 通过 reinterpret_cast 的非对齐访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32589328/

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