C++ 将转换缩小到更大的类型(然后再缩小)

C++ 将转换缩小到更大的类型(然后再缩小),c++,c++11,C++,C++11,据我所知,从C++11开始,从int到unsigned long的转换被认为是一种窄化转换,因为unsigned long不能表示任何负值,尽管它足够大,可以表示所有位。我的问题是,如果我强制转换,然后转换回int,我是否保证得到相同的值(特别是指它既不是未定义的行为,也不是实现定义的行为) 这些值,j和n是否保证与i和ll相同(当然分别)?是否有任何可移植性或体系结构(32位与64位)问题需要考虑?您的两个示例都是实现定义的 有符号到无符号的转换定义良好,conv.integral/2: 如果

据我所知,从C++11开始,从
int
unsigned long
的转换被认为是一种窄化转换,因为
unsigned long
不能表示任何负值,尽管它足够大,可以表示所有位。我的问题是,如果我强制转换,然后转换回
int
,我是否保证得到相同的值(特别是指它既不是未定义的行为,也不是实现定义的行为)


这些值,
j
n
是否保证与
i
ll
相同(当然分别)?是否有任何可移植性或体系结构(32位与64位)问题需要考虑?

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

有符号到无符号的转换定义良好,conv.integral/2:

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

但是,只有在源值可以在目标类型conv.integral/3中表示的情况下,无符号到有符号的转换才能得到很好的定义:

如果目标类型是有符号的,则该值将保持不变(如果可以) 以目标类型(和位字段宽度)表示;否则,, 该值由实现定义

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

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?
long long ll = -281474976710655LL;
unsigned long long ull = static_cast<unsigned long long>(ll);
long long n = static_cast<long long>(ull);