当表达式中的所有项都是 uint8_t 时,如何存储算术表达式中中间步骤的结果?

How are the results of intermediate steps in an arithmetic expression stored when all terms in the expression are uint8_t?

代码:

int main(void) {
    uint8_t x = 3;
    uint8_t y = 4;
    uint8_t z = 5;

    uint8_t a = (x - y) / z;
    uint8_t b = x - y;
    printf("a is %d\n", a);
    printf("b is %d\n", b);
    return 0;
}

有以下输出:

a is 0
b is 255

我希望 (3 - 4) / 5 会导致溢出,因为 (3 - 4) 因为 uint8_t 是 255。当涉及无符号整数的中间步骤导致负数时,为什么不它溢出了吗?在下一步 / 5 发生之前,(3 - 4) 的结果以什么格式存储?

可以使用一个更简单的示例来了解实际情况:

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

int main(void) {
    uint8_t x = 3;
    uint8_t y = 4;

    int a = (x - y);
    printf("a is %d\n", a);    // a is -1
    return 0;
}

(实例:http://ideone.com/C3SlIn)

您所看到的是 整数提升 的结果,作为 通常 - 的操作数的一部分算术转换.1 (C99) 标准中整数提升定义的相关部分:

[6.3.1.1] If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int.

一个int确实可以表示一个uint8_t的所有值,所以减法真的等价于:

int a = (int)x - (int)y;

也就是说没有溢出


1.但是为了避免一个常见的混淆,这种行为是 固有的 - 的工作方式;这不是因为我们在这里分配给 int