将转化范围缩小到更大的类型(并再次返回)

时间:2017-11-06 17:14:42

标签: c++ c++11

我理解,从C ++ 11开始,从intunsigned long long的转换被视为缩小转换,因为unsigned long long不能代表任何负值,尽管它足够大以表示所有的比特。我的问题是,如果我强制转换然后转换回int,我保证获得相同的值(具体意味着它既不是未定义也不是实现定义的行为)?

int i = -42;
unsigned long long ull = static_cast<unsigned long long>(i);
int j = static_cast<int>(ull); // is this guaranteed to be -42?

此外,我想知道只有类型的signed更改的情况:

long long ll = -281474976710655LL;
unsigned long long ull = static_cast<unsigned long long>(ll);
long long n = static_cast<long long>(ull);

这些值,jn是否保证与ill相同(当然)?是否存在需要考虑的可移植性或体系结构(32对64位)问题?

1 个答案:

答案 0 :(得分:3)

您的两个示例都是实现定义的。

签名到无符号转换已明确定义,conv.integral / 2:

  

如果目标类型是无符号的,则结果值最小   无符号整数与源整数一致(模2 n ,其中n为   用于表示无符号类型的位数。)

但是,如果源值可以在目标类型conv.integral / 3中表示,则无符号签名转换只能很好地定义:

  

如果目标类型已签名,则值可以保持不变   以目标类型(和位字段宽度)表示;除此以外,   该值是实现定义的。

对于这两个示例,无法表示源值(因为两个无符号值都大于有符号数的最大可能值),因此这些转换是实现定义的。