算术运算期间的数据类型提升:-1 <(unsinged int)1 == false

bak*_*kra 10 c unsigned integer-promotion

main()  {   
  if ( -1 < (unsigned char) 1 )
    printf("less than");
  else        
    printf("NOT less than");
} 
Run Code Online (Sandbox Code Playgroud)

打印less than.因为,(unsigned char) 1 转换为 (signed char) 1然后:(signed) -1 < (signed) 1,因此输出less than.

但是,如果我将上面的代码更改if ( (-1 < (unsigned int) 1 )

那么输出就是NOT less than.

所以很明显,当我将unsigned char更改为unsigned int时:

  • (signed)-1转换为unsigned int [正好相反]
  • 因为-1被存储为2的恭维1; 位模式评估为255(可能)
  • 因此255 <1将评估为false,否则将执行.
  • 即使你代替int a = -1;'-1'相同的结果替代

问题:

  1. 在有符号和无符号算术期间...如何确定签名是否将转换为无符号或反之亦然.

  2. 为什么unsigned char和char之间的算术转换不同:显然unsigned转换为signed和unsigned int和int:显然签名转换为unsigned

PS:我知道这不依赖编译器.所以不要说它.

Mar*_*ers 10

规则如下:

6.3.1.8通常的算术转换

...

否则,将对两个操作数执行整数提升.然后将以下规则应用于提升的操作数:

  1. 如果两个操作数具有相同的类型,则不需要进一步转换.
  2. 否则,如果两个操作数都具有有符号整数类型或两者都具有无符号整数类型,则具有较小整数转换等级类型的操作数将转换为具有更高等级的操作数的类型.
  3. 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型.
  4. 否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为带有符号整数类型的操作数的类型.
  5. 否则,两个操作数都转换为无符号整数类型,对应于带有符号整数类型的操作数的类型.

然后规则如下:

  • -1 < (unsigned char) 1

首先将两个操作数转换为整数(因为int可以表示unsigned char的所有值).然后对这些签名类型进行比较.然后使用规则1.比较成功.

  • -1 < (unsigned int) 1

int不能表示unsigned int的所有值,因此使用规则3并且有符号整数将转换为无符号整数(UINT_MAX - 1).比较现在失败了.