C:gcc中的uint16_t减法行为

我试图减去两个无符号整数并将结果与​​有符号整数(或文字)进行比较。 使用unsigned int类型时,行为符合预期。 当使用uint16_t (来自stdint.h )类型时,行为不是我所期望的。 使用gcc 4.5进行比较。
给出以下代码:

 unsigned int a; unsigned int b; a = 5; b = 20; printf("%u\n", (ab) < 10); 

输出为0,这是我的预期。 a和b都是无符号的,并且b大于a,因此结果是一个大的无符号数,大于10.现在如果我改变a和b来输入uint16_t:

 uint16_t a; uint16_t b; a = 5; b = 20; printf("%u\n", (ab) < 10); 

输出为1.这是为什么? 两个uint16_t类型之间的减法结果是存储在gcc中的int中吗? 如果我将10更改为10U则输出再次为0,这似乎支持这一点(如果减法结果存储为int并且与无符号int进行比较,则减法结果将转换为unsigned int)。

因为计算不是使用int / unsigned int(char,short,unsigned short等;但不长,unsigned long等)的类型,但它们首先被提升为int或unsigned int之一。 “uint16_t”在您的实现上可能是“unsigned short”,在您的实现上被提升为“int”。 因此,该计算的结果是“-15”,小于10。

在使用16位计算的较旧实现中,“int”可能无法表示“unsigned short”的所有值,因为两者具有相同的位宽。 此类实现必须将“unsigned short”提升为“unsigned int”。 在这样的实现中,您的比较结果为“0”。

在执行-<操作之前,将应用一组称为常规算术转换的转换 ,以将操作数转换为公共类型。 作为此过程的一部分,将应用整数提升 ,这会将类型比intunsigned int更窄的类型提升为这两种类型之一。

在第一种情况下, ab的类型是unsigned int ,因此由于-运算符而不会发生类型更改 - 结果是具有大正值UINT_MAX - 14unsigned int 。 然后,因为intunsigned int具有相同的等级,所以将类型为int的值10转换为unsigned int ,然后执行比较,得到值0

在第二种情况下,很明显,在您的实现中, int类型可以包含uint16_t类型的所有值。 这意味着当应用整数提升时, ab的值将提升为int类型。 执行减法,得到类型为int的值-15<两个操作数都是int ,因此不执行任何转换; <的结果是1

在后一种情况下使用10U时, a - b的结果仍为-15 ,类型为int 。 但是,现在,通常的算术转换会导致此值转换为unsigned int (就像第一个示例中的10那样),这会产生值UINT_MAX - 14 ; <的结果为0