C中的类型推广
我对以下代码感到困惑:
#include #include int main(int argc, char ** argv) { uint16_t a = 413; uint16_t b = 64948; fprintf(stdout, "%u\n", (a - b)); fprintf(stdout, "%u\n", ((uint16_t) (a - b))); return 0; }
返回:
$ gcc -Wall test.c -o test $ ./test 4294902761 1001 $
似乎表达式(a-b)具有类型uint32_t。 我不明白为什么因为两个运算符都是uint16_t。
任何人都可以向我解释这个吗?
C标准非常清楚地解释了这一点(§6.5.6加法运算符):
如果两个操作数都具有算术类型, 则对它们执行通常的算术转换 。
(§6.3.1.8通常的算术转换):
…在两个操作数上执行整数提升 。
(§6.3.1.1布尔,字符和整数):
如果
int
可以表示原始类型的所有值,则该值将转换为int
; …这些被称为整数促销。 整数促销不会更改所有其他类型。
由于int
可以表示平台上uint16_t
所有值,因此在执行减法之前, a
和b
将转换为int
。 结果的类型为int
,并作为int
传递给printf
。 您已使用int
参数指定了%u
格式化程序; 严格来说,这会调用未定义的行为,但在您的平台上, int
参数被解释为它的二进制补码表示,并且打印出来。
如果丢弃一个数字的顶端位(通过显式转换为16位无符号整数),那么你将得到一个小于(在0和2 ^ 16-1范围内)的结果。之前。
在进行减法之前,C会将参数提升为unsigned int
。 这是标准行为。
例如,请参阅在一个C表达式中,其中存在unsigned int和signed int,哪种类型将被提升为什么类型? 详情。