对于 ((无符号整数)0-1)返回 true>0

returns true for ((unsigned int)0-1)>0

本文关键字:gt 返回 无符号整数 对于 true      更新时间:2023-10-16

我遇到了一些C 代码,就像

if(((unsigned int)0-1)>0)
{
//do something
}

和程序在if块中执行语句。很好奇,我在C中尝试了同样的事情,这也是如此。我的理解是,如果if条件中的表达式返回bool值true,则if块中的语句将执行。这意味着(((unsigned int)0-1)> 0必须返回正确。为什么会发生?

对于(unsigned int)0-1operator-的操作数为unsigned int 0int 1。然后结果的类型(即常见类型)为 unsigned int

否则,如果未签名的操作数的转换等级更大或等于签名操作数的转换等级,则将签名的操作数转换为无符号操作数的类型。

对于unsigned int,它不可能是0-1,而是

始终执行未签名的整数算术算法 modulo 2 n 其中n是该特定整数中的位数。例如。对于unsigned int,将一个添加到Uint_max给出0,然后从​0中减去Uint_max。

这意味着if(((unsigned int)0-1)>0)等于if(UINT_MAX>0),即true

if(((unsigned int)0-1)>0)

使用普通算术,0-1为负一个,不大于零。我们在这里没有处理普通算术。

C (以及C)优先规则说,铸造优先于减法,因此(unsigned int)0-1等于((unsigned int) 0)-1。换句话说,0被视为unsigned int

接下来,我们有一个unsigned int减去签名的int。有关此类操作的C (和C)规则是将签名值视为未签名。关于未签名操作的C (和C)规则是执行计算模型2 n ,其中n是公共类型中的位数(通常为int,但不能保证那)。 0-1 modulo 2 n 是2 n -1,是(大)正数。

引用标准,[basic.fundamental]第4段,

未签名的整数,声明为未签名,应遵守算法模型2 n ,其中 n 是值表示中的位数整数的特殊大小。 46

和脚注:

46)这意味着未签名的算术不会溢出,因为结果不能用结果的未签名整数类型表示的结果减少了一个比最大值的数字大于最大值,而最大值的数字是由结果无签名的无签名的Integer类型所代表的。