重新解释数据会是未定义的行为吗?

Lal*_*5th 9 c++ undefined-behavior

最近有人提出这个:

uint8_t a = 0b10000000;
int8_t b = *(int8_t*) &a;
Run Code Online (Sandbox Code Playgroud)

是未定义的行为,因为 的值a超出了我在int8_t. 有人可以解释为什么这是未定义的行为吗?

我的主要问题是内存在那里,并且作为 的内存有效int8_t,唯一的区别是int8_t将该字节解释为-128,而uint8_t将其解释为128。我对此感到更加困惑,因为快速平方根反函数使用:

float y =  /* Some val*/;
int32_t i  = * ( int32_t * ) &y; 
Run Code Online (Sandbox Code Playgroud)

这将给出一个i本质上与 无关的值(除了 IEEE 标准)y,所以我不明白为什么重新解释一段内存可能是未定义的行为。

Lal*_*5th 9

感谢所有的评论。我进入了一个严格混叠的兔子洞,发现快速平方根是未定义的行为,尽管我相信,但我的初始代码似乎不是。不是因为它uint8_t很特殊,而是因为标准有一个关于有符号/无符号交换的规则:

如果程序尝试通过类型与以下类型之一不相似的泛左值访问对象的存储值,则行为未定义: [...] (11.2) 对应于有符号或无符号类型的类型对象的动态类型

所以理论上没有问题,uint8_t无符号类型的int8_t

  • @FatihBAKIR 它们的定义在 C 标准 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf(第 255 页)中。“当定义的 typedef 名称仅在初始 u 不存在或存在时不同,它们应表示相应的有符号和无符号类型”。C++ 标准明确定义这些类型遵循 C 标准 (4认同)
  • @FatihBAKIR:C++ 从 C 继承了 `<cstdint>` 类型(C++ 标准是指这些导入头文件的规范的 C 标准)。C 2018 7.20.1 1 说,当定义这些 typedef 名称时,“它们应表示对应的有符号和无符号类型,如 6.2.5 中所述……”因此 `int8_t` 和 `uint8_t` 是对应的有符号和无符号类型。 (4认同)