C中的类型推广

时间:2011-10-31 13:59:31

标签: c types integer-promotion

我对以下代码感到困惑:

#include <stdio.h>
#include <stdint.h>

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。

任何人都可以向我解释这个吗?

3 个答案:

答案 0 :(得分:14)

C标准非常清楚地解释了这一点(§6.5.6加法运算符):

  

如果两个操作数都有算术类型,则对它们执行通常的算术转换

(§6.3.1.8通常的算术转换):

  

...对两个操作数执行整数提升

(§6.3.1.1布尔,字符和整数):

  

如果int可以表示原始类型的所有值,则该值将转换为int; ......这些被称为整数促销。所有其他类型都不会被整数促销更改。

由于int可以代表您平台上uint16_t的所有值,因此ab会在执行减法之前转换为int。结果的类型为int,并作为printf传递给int。您已使用%u参数指定了int格式化程序;严格来说,这会调用未定义的行为,但在您的平台上,int参数被解释为它的二进制补码表示,并且打印出来。

答案 1 :(得分:1)

如果丢弃一个数字的顶端位(通过显式转换为16位无符号整数),那么你将得到一个更小的结果(在0和2 ^ 16-的范围内) 1)比以前。

答案 2 :(得分:0)

C在进行减法之前将参数提升为unsigned int。这是标准行为。

例如,请参阅In a C expression where unsigned int and signed int are present, which type will be promoted to what type?了解详情。