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

Why is the type of (-i), where i is unsigned int, still unsigned int?

本文关键字:int 无符号 仍然是 其中 类型 为什么      更新时间:2023-10-16
int main() {
unsigned int i = 1;
typeof(-i) j = -i;
}

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

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

一元-运算符的结果是其(提升的(的负数 操作数。整数提升对操作数执行,并且 结果具有升级类型

整数升级的详细信息在第 6.3.1.1p2 节中详细介绍:

以下内容可用于表达式中,无论intunsigned int可用于:

  • 整数类型(intunsigned int除外(的对象或表达式,其整数转换排名小于或等于intunsigned int的军衔.
  • 类型为_Boolintsigned intunsigned int的位域。

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

i的类型是unsigned int根据上述段落不受整数促销的影响(实际上,它是整数促销的目标类型(。 因此,不执行任何升级,并且-i的类型与i的类型相同。

对无符号类型的否定不会产生有符号的负值,因为无符号否定是有意义和有用的。

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

无符号算术可以模拟二的补码;在这种情况下,否定充当二的补码运算符:它"翻转所有位并加一"。例如,-0x1U0xFF...FFU