C:gcc中的uint16_t减法行为

时间:2012-04-06 18:56:54

标签: c gcc unsigned stdint

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

unsigned int a;
unsigned int b;

a = 5;
b = 20;

printf("%u\n", (a-b) < 10);

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

uint16_t a;
uint16_t b;

a = 5;
b = 20;

printf("%u\n", (a-b) < 10);

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

2 个答案:

答案 0 :(得分:6)

因为计算不是使用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”。

答案 1 :(得分:3)

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

在第一种情况下,ab的类型为unsigned int,因此-运算符不会发生类型更改 - 结果为{ {1}}具有较大的正值unsigned int。然后,由于UINT_MAX - 14int具有相同的排名,因此将类型为unsigned int的值10转换为int,然后执行比较,值unsigned int

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

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