将float
值的位模式复制到uint32_t
或反之亦然(不是强制转换),我们可以使用std::copy
或{{1}来逐字节复制位}。另一种方法是使用memcpy
,如下所示:
reinterpret_cast
或
float f = 0.5f;
uint32_t i = *reinterpret_cast<uint32_t*>(&f);
但是有claim表示上面使用的两个uint32_t i;
reinterpret_cast<float&>(i) = 10;
,会调用未定义的行为。
这是真的吗?怎么样?
答案 0 :(得分:6)
是的,这是未定义的行为,因为它违反了严格的别名规则:
[basic.lval]/10:
如果程序试图通过除了其中一个之外的glvalue访问对象的存储值 以下类型的行为未定义 - 对象的动态类型,- 对象的动态类型的cv限定版本,
- 与对象的动态类型相似的类型(如4.4中所定义)
- 与对象的动态类型对应的有符号或无符号类型
- 对应于动态类型的cv限定版本的有符号或无符号类型 对象,
- 聚合或联合类型,包括其元素中的上述类型之一或非 静态数据成员(包括递归地,子集合的元素或非静态数据成员) 或包含联盟),
- 一种类型,是对象动态类型的(可能是cv-qualifded)基类类型,
- char或unsigned char类型。
由于uint32_t
在尝试访问类型为float
的对象时不属于上述情况,因此行为未定义。