【发布时间】: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