C++中unsigned int转int/long的行为是否合规?相关规则解析
问题分析:无符号数取负与函数参数转换的行为
原代码
#include <iostream> using namespace std; void fun1(int off) { cout << "fun1 " << off << endl; } void fun2(long off) { cout << "fun2 " << off << endl; } int main() { unsigned int a; a = 50; fun1(-a); fun2(-a); return 0; }
程序输出
fun1 -50 fun2 4294967246
修改后的情况
若将unsigned int a修改为unsigned long a,则两次输出均为-50。
问题解答
该行为是否属于C++标准定义的良好行为?
是,所有上述行为都符合C++标准的定义,属于定义良好的行为。
对应的相关规则
无符号整数的取负运算
C++标准规定,对无符号整数执行取负(-)操作时,结果是该无符号数对应模2^N的补数(N为该无符号类型的位数)。以32位unsigned int为例,-a等价于UINT_MAX - a + 1,这里a=50时计算结果为4294967246,是合法的unsigned int值。函数参数的隐式转换规则
- 调用
fun1(-a)时:-a的结果是unsigned int类型,需要转换为int类型。由于4294967246超出32位有符号int的范围(-2147483648到2147483647),C++标准规定此时直接将无符号数的二进制位模式按目标有符号类型的补码规则解释,4294967246的二进制为0xFFFFFFCE,作为32位有符号int时正好表示-50。 - 调用
fun2(-a)时:-a的结果是32位unsigned int,转换为64位long类型时,由于无符号值的最大值小于long的最大值,会直接进行零扩展,结果为4294967246,输出时按正数打印。
- 调用
修改为
unsigned long后的逻辑
当a是64位unsigned long时,-a的结果为ULONG_MAX -50 +1,该值的二进制位模式作为64位有符号long解释时,正好是-50的补码;转换为32位int时,截断后的二进制位模式同样对应-50,因此两次输出均为-50。
内容的提问来源于stack exchange,提问作者Mingfei Gao
相关产品推荐
相关产品推荐

