C:gcc中的uint16_t减法行为

Avi*_*Avi 1 c unsigned gcc stdint

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

unsigned int a;
unsigned int b;

a = 5;
b = 20;

printf("%u\n", (a-b) < 10);
Run Code Online (Sandbox Code Playgroud)

输出为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);
Run Code Online (Sandbox Code Playgroud)

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

Joh*_*itb 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".


caf*_*caf 5

在执行-<运算之前,应用一组称为常用算术转换的转换来将操作数转换为通用类型。作为此过程的一部分,整数促销被施加,这促进了类型窄于intunsigned int以这两种类型之一。

在第一种情况下,aand的类型bunsigned int,因此不会因-运算符而发生类型变化- 结果是unsigned int具有大正值的an UINT_MAX - 14。然后,因为intunsigned int具有相同的等级,10具有类型的值int被转换为unsigned int,然后执行比较结果为值0

在第二种情况下,很明显,在您的实现中 typeint可以保存type 的所有值uint16_t。这意味着当施加整数促销,的值即ab被提升到键入int。执行减法,得到-15类型为 的值int。的两个操作数<都已经是int,因此不执行任何转换;的结果<1

10U在后一种情况下使用 a时,结果a - b仍然-15是 type int。然而,现在通常的算术转换会导致这个值被转换为unsigned int(就像10第一个例子中的 ),结果是值UINT_MAX - 14; 的结果<0