为什么(-i)的类型(其中i是无符号整数)仍然是无符号整数?

时间:2019-11-25 18:22:57

标签: c++ c clang

int main() {
    unsigned int i = 1;
    typeof(-i) j = -i;
}

当我查看gdb中的j类型时,它显示为unsigned int类型。为什么类型没有移动到相应的带符号类型?选择这种行为背后有什么原因吗?我发现该类型是否可以更直观地转换为相应的带符号类型。

2 个答案:

答案 0 :(得分:5)

一元求反运算符-除了应用整数提升外,不会更改其参数类型。 C standard的6.5.3.3p3节规定:

  

一元-运算符的结果为其负数(提升)   操作数。整数提升是在操作数上执行的,   结果具有提升的类型

有关整数促销的详细信息,请参见第6.3.1.1p2节:

  

以下表达式可在int或   可以使用unsigned int

     
      
  • 具有整数类型(intunsigned int除外)的对象或表达式,其整数转换等级小于或等于   intunsigned int的排名。
  •   
  • _Boolintsigned intunsigned int类型的位域。
  •   
     

如果int可以表示原始类型的所有值(如   受宽度限制(对于位字段),该值将转换为   int;否则,它将转换为unsigned int。这些是   称为整数促销。所有其他类型均未更改   整数促销。

i的类型为unsigned int,根据上面的段落,它不受整数促销的限制(实际上,它是整数促销的目标类型)。因此,不执行升级,-i的类型与i的类型相同。

答案 1 :(得分:1)

无符号类型的求反不会产生带符号的负值,因为无符号的求反是有意义且有用的。

首先,对于给定的无符号值a,存在一个无符号值b,使得a + b == 0。将b标识为-a,并反之亦然:在该类型的模算法下,它是一种加法逆运算。

无符号算术可以模拟二进制补码;在这种情况下,取反用作二进制补码运算符:它“翻转所有位并加1”。例如,-0x1U0xFF...FFU