gpt4 book ai didi

c++ - 这是否违反了严格的别名或指针对齐规则?

转载 作者:行者123 更新时间:2023-11-28 05:38:26 25 4
gpt4 key购买 nike

我正在交换字符缓冲区中的字节:

char* data; // some char buffer
uint16_t* data16 = reinterpret_cast<uint16_t*>(data);

// For debugging:
int align = reinterpret_cast<uintptr_t>(data) % alignof(uint16_t);
std::cout << "aligned? " << align << "\n";

for (size_t i = 0; i < length_of_data16; i++) {
#if defined(__GNUC__) || defined(__clang__)
data16[i] = __builtin_bswap16(data16[i]);
#elif defined(_MSC_VER)
data16[i] = _byteswap_ushort(data16[i]);
#endif
}

我正在从 char* 转换为 uint16_t*,这会引发一个标志,因为它正在转换为更严格对齐的类型。

但是,代码运行正确(在 x86 上),即使调试代码打印 1(如未对齐)。在程序集中,我看到了 MOVDQU,我认为这意味着编译器认识到这可能没有对齐。

这看起来类似于 this question ,答案是“这不安全”。上面的代码是否只适用于特定的体系结构和特定的编译器,或者这两个问题之间是否存在使上面的代码有效的细微差别?

(不太重要:与我在网上阅读的内容一致,此代码的对齐和未对齐执行之间也没有明显的性能差异。)

最佳答案

如果 alignof(unit16_t) != 1 则此行可能会由于对齐而导致未定义的行为:

uint16_t* data16 = reinterpret_cast<uint16_t*>(data);

之后进行对齐检查是不好的;因为编译器可以将检查硬编码为1,因为它知道正确的代码无法到达那个点。

在标准 C++ 中,要使此检查有意义,它必须发生在强制转换之前,如果检查失败,则不得执行强制转换。 (UB 可以进行时间旅行)。

当然,个别编译器可能会选择定义标准未定义的行为,例如也许针对 x86 或 x64 的 g++ 包含一个定义,允许您形成未对齐的指针并取消引用它们。

没有严格的别名违规,因为 __builtin_bswap16 没有被标准覆盖,我们假设 g++ 以与自身一致的方式实现它。无论如何,MSVC 不会进行严格的别名优化。

关于c++ - 这是否违反了严格的别名或指针对齐规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37714539/

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