2016-08-03 118 views
0

float值的位模式复制到uint32_t或反之亦然(而不是它们),我们可以使用std::copymemcpy复制位字节到字节。另一种方法是如下使用reinterpret_cast复制位模式:浮点数到uint32_t

float f = 0.5f; 
uint32_t i = *reinterpret_cast<uint32_t*>(&f); 

uint32_t i; 
reinterpret_cast<float&>(i) = 10; 

但是有一个claim是说,两名reinterpret_cast上面使用,调用未定义的行为。

这是真的吗?怎么样?

+1

正如答案所述,它是UB。一个断言“sizeof(uint32_t)== sizeof(float)'虽然应该是所有你需要确信它会起作用的。 – NathanOliver

+0

@NathanOliver但是,如果编译器进行基于类型的别名优化,那么如果你不提供'-fno-strict-aliasing'或其他东西,它可以合理地破坏行为。 – TartanLlama

+0

@TartanLlama好点。检查'alignof'也可能是需要的。 – NathanOliver

回答

6

对,这是不确定的行为,因为它破坏了严格别名规则:

[basic.lval]/10:如果一个程序试图通过的其他一个glvalue比 以下类型之一来访问对象的存储值的行为是未定义 - 动态类型的对象,

- 动态类型的对象的CV-合格版本,

- 类似于一个类型(在4.4中定义的)到t他动态对象的类型,

- 一个类型是有符号或对应的动态对象的类型无符号类型,

- 在所述签名或相应于CV-合格的无符号类型的类型对象的动态类型 的版本,

- 在其元素或非元素中包含上述类型之一的聚合或联合类型静态数据成员(包括递归的元素或非静态数据成员的亚集团 或包含的联盟),

- 一种类型,它是对象的动态类型的基本类型(可能是cv-qualifded),

- char或unsigned char类型。

由于uint32_t在尝试访问float类型的对象时没有出现上述情况,因此行为未定义。