我理解,从C ++ 11开始,从int
到unsigned 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);
这些值,j
和n
是否保证与i
和ll
相同(当然)?是否存在需要考虑的可移植性或体系结构(32对64位)问题?
答案 0 :(得分:3)
您的两个示例都是实现定义的。
签名到无符号转换已明确定义,conv.integral / 2:
如果目标类型是无符号的,则结果值最小 无符号整数与源整数一致(模2 n ,其中n为 用于表示无符号类型的位数。)
但是,如果源值可以在目标类型conv.integral / 3中表示,则无符号签名转换只能很好地定义:
如果目标类型已签名,则值可以保持不变 以目标类型(和位字段宽度)表示;除此以外, 该值是实现定义的。
对于这两个示例,无法表示源值(因为两个无符号值都大于有符号数的最大可能值),因此这些转换是实现定义的。