C中的类型推广

Jul*_*ULD 6 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;
}
Run Code Online (Sandbox Code Playgroud)

返回:

$ gcc -Wall test.c -o test
$ ./test
4294902761
1001
$ 
Run Code Online (Sandbox Code Playgroud)

似乎表达式(a-b)具有类型uint32_t.我不明白为什么因为两个运算符都是uint16_t.

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

Ste*_*non 14

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

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

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

... 在两个操作数上执行整数提升.

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

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

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


unw*_*ind 0

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

例如,在存在 unsigned int 和signed int 的 C 表达式中,哪种类型将提升为哪种类型?了解详情。