正如您所做的那样,到有符号整数类型的超出范围转换是实现定义的。
在您可能遇到的大多数实现中,将 a 的最大值转换为uint32_t
aint32_t
意味着保留位模式并将其视为有符号值。这意味着它b1
被分配了值-1。
然后比较a1
andb1
时,将应用通常的算术转换。这些在C 标准的第 6.3.1.8 节中有详细说明:
如果两个操作数具有相同的类型,则不需要进一步转换。
否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则具有较小整数转换等级的类型的操作数将转换为具有较高等级的操作数的类型。
否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。
否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。
否则,两个操作数都转换为与带符号
整数类型的操作数类型对应的无符号整数类型
在这种情况下,突出显示的部分是适用的,因为uint32_t
和int32_t
具有相同的等级,所以 的值b1
被转换为 type uint32_t
。
当为无符号类型转换超出范围的值时,这是通过在数值上重复地增加或减去无符号类型的最大值,直到该值在范围内。这实际上意味着源值的任何多余字节都将被截断,剩下的将被视为无符号值。
这种转换在C 标准的第 6.3.1.3 节中有详细说明:
1当整数类型的值转换为除 以外的其他整数类型_Bool
时,如果该值可以用新的类型表示,则保持不变。
2否则,如果新类型是无符号的,则在新类型可以表示的最大值的基础上反复加减一,直到该值在新类型的范围内。
3否则,新类型是有符号的,值不能在其中表示;结果是实现定义的或引发了实现定义的信号
在这种情况下,第 3 段适用于您第一次分配a1
给 时b1
,然后第 2 段适用于您进行比较并b1
转换时。这意味着值 -1 被转换为 value UINT32_MAX
,这就是比较结果为 true 的原因。