【问题标题】:Is conversion between exactly-sized integers always completely defined by the standard?精确大小的整数之间的转换是否总是完全由标准定义?
【发布时间】:2015-12-24 17:57:53
【问题描述】:

考虑以下代码:

#include <cstdint>
#include <iostream>
#include <iomanip>

int main()
{
    auto x=std::uint32_t(1)<<31;
    std::cout << " x: 0x" << std::hex << x << " =  " << std::dec << x << "\n";
    int32_t sx=x;
    std::cout << "sx: 0x" << std::hex << sx << " = " << std::dec << sx << "\n";
}

我从中得到以下输出:

 x: 0x80000000 =  2147483648
sx: 0x80000000 = -2147483648

这里x 的值不能用int32_t 表示,C++11 标准对这种转换有如下说明:

如果目标类型是有符号的,则如果它可以在目标类型中表示,则值不变(并且 位域宽度);否则,该值是实现定义的。

即使使用intXX_t,这仍然是实现定义的,我们对表示有一定的保证? 如果是,那么如何保证结果如上图所示?我应该memcpy我的无符号值签名以获得二进制补码解释,还是有更直接的方法?

【问题讨论】:

  • memcpy 从一种类型到另一种类型会产生未定义的行为,因此这不是一个理想的解决方法。
  • @AlanStokes 根据this 似乎不给UB。
  • “解决”这个问题的一种方法是将可移植性限制在 implementation-defined 意味着它可以按预期工作的系统上。在转换陷阱的系统上,您可能会遇到比这更严重的问题。
  • 那个链接说memcpy遵守别名规则,所以如果你知道类型的布局就可以了。但是你一般不知道int32_t的布局,虽然保证用2s补码。

标签: c++ type-conversion


【解决方案1】:

int32_t sx=x;实现定义的

您引用的规则是将一个值转换为该值超出范围的类型会导致实现定义的行为。

int32_t 的范围上升到 INT32_MAX,即2147483647,但(uint32_t)1 &lt;&lt; 31 不止于此。

与表示无关,只看值能否保持不变。

使用memcpy 将生成int32_t,它与您从中复制的其他值具有相同的表示(我认为这是明确定义的,因为int32_t 不能有填充或陷阱)

【讨论】:

  • 使用memcpy 应该可以,但它需要比您在答案中提供的更强大的保证。重要的是 C 标准指定 int32_tuint32_t对应 有符号和无符号整数类型,这基本上意味着它们的表示必须匹配,无符号版本的最高值位映射到有符号版本的符号位。如果没有这个要求,恶意实现可能会使其中一个为大端,另一个为小端。
  • @hvd C++中有类似的保证吗?
  • @AlanStokes 该保证也适用于 C++,因为 C++ 指定 int32_tuint32_t(如果存在)表示它们在 C 中所做的相同事情。
  • @hvd 是的,严格的别名规则特别允许这种情况
  • @M.M 啊,对!所以 应该 意味着 memcpy 不需要,int32_t sx=(int32_t&amp;)x; 也应该工作。
【解决方案2】:

是的,它是实现定义的。

无符号 32 位整数类型(例如 uint32_t)可以表示的值不能保证有符号 32 位整数类型(int32_t)能够表示。其中一个值正在您的代码中生成。因此,您从 C++11 中引用的子句是适用的。

【讨论】:

    【解决方案3】:

    我认为它是实现定义的,因为不能保证 2 的恭维。 (想象一个单独的符号位)。

    因此不存在安全机制。

    【讨论】:

    • int32_t 保证正好是 32 位和 2 的补码。否则 typedef 将不存在。
    • @Bo Persson,这里的代表保证是两个人的恭维。我不知道有任何奇怪的实现,但我认为它们会合规
    猜你喜欢
    • 2013-10-06
    • 2014-04-03
    • 2020-05-25
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    相关资源
    最近更新 更多