请考虑以下代码:
#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
签署我的无符号值以获得两个补码解释,还是有更简单的方法?
答案 0 :(得分:3)
int32_t
是实现定义的。
您引用的规则是将值转换为该值超出范围的类型会导致实现定义的行为。
INT32_MAX
的范围最高为2147483647
(uint32_t)1 << 31
,但memcpy
只是其中之一。
它与表示无关,而是关于值是否可以保持不变。
使用int32_t
会生成int32_t
,它与您复制的其他值具有相同的表示形式(我认为这是明确定义的,因为GET
不能有填充或陷阱)< / p>
答案 1 :(得分:1)
是的,它是实现定义的。
有些值表示无符号32位整数类型(例如uint32_t
)可以表示无法保证能够表示带符号的32位整数类型(int32_t
)。其中一个值正在您的代码中生成。因此,您引用C ++ 11的条款是适用的。
答案 2 :(得分:0)
我认为这是实施定义,因为不能保证2的赞美。 (想象一下单独的标志位。)
因此不存在安全机制。