不允许使用reinterpret_cast <int>(aFloatValue)的C ++标准的基本原理是什么?

时间:2016-09-11 01:32:06

标签: c++ floating-point

或等效

    reinterpret_cast<int64>( aDoubleValue )

允许这样的reinterpret_cast不会引入任何别名问题。

据我所知,使用memcpy将一个类型的变量中的字节复制到另一个类型的变量中可以达到必要的效果。我理解具有强大优化器的成熟编译器可以使用这样的memcpy构造做很棒的事情。

那说我碰巧是编译器 - 编写者。我非常了解必须存在的许多优化形式以及必须满足的许多前提条件才能实现这些显着的优化。我们真的想要假设每个编译器都是那么强大,或者每个程序员都会成功编写满足所有必要前提条件的代码吗?我们真的可以让使用非主流编译器的程序员误认为会发生这种希望的优化吗?

需要检查浮点值的位数。我们是否真的想要坚持每个程序员遇到这样的需求流量在地址采集变量,char *异常键入别名规则,memcpy魔术等?

2 个答案:

答案 0 :(得分:1)

&#34; new&#34; (现在已经很老了)用C ++提供的转换形式基本上都是你可以用C风格的演员表做的事情的子集(&#34;基本上&#34;因为他们有一些小的补充,比如处理引用,只是没有&# 39; t存在于C)中。

要获得与C风格演员表相同的reinterpret_cast,您可以执行以下操作:

int a = *(int *)&some_float;

因此,使用reinterpret_cast,您可以执行相同的操作,只需使用reinterpret_cast更改投射本身的语法:

int a = *reinterpret_cast<int *>&some_float;

至于定义它的作用,所以你可以在不违反任何严格别名规则的情况下做到这一点:我怀疑委员会可能会很乐意考虑一个写得很好的提案 - 我怀疑现在的问题是大多数认为这需要很多工作,而且回报很小。

如果真正的意图是支持查看浮点数的位,那么定义类似于bitset::bitset<float>的构造函数或该订单上的某些内容可能更简单,以提供类型为&#39 ; s已经明确定义为允许访问位(尽管定义它应该以一种“便携式”方式工作的方式仍然可能是非常重要的。)

答案 1 :(得分:0)

如果您想要的只是一个将float转换为其位序列的函数,memcpy可以在不违反严格别名规则的情况下执行此操作:

unsigned int ConvertFloat(float f)
{
  unsigned int ret;
  std::memcpy(&ret, &f, sizeof(unsigned int));
  return ret;
}

Live example.

您甚至可以制作一般模板功能,将一种类型转换为另一种类型。一个会static_assert或SFINAE-检查参数是否可以轻易复制。

在你的工作中,将浮点数转换为整数是一种半频繁的操作。但对于大多数C ++用户(甚至大多数C用户)而言,情况并非如此。因此,对于这样的转换操作没有广泛的 need

此外,C ++标准并不要求实现提供float的任何特定表示。因此,即使标准提供了这样的功能,也无法告诉您实际返回的内容。甚至不能保证float可以放入unsigned int