临时操作会导致 8 位嵌入式系统溢出吗?

Do temporary operations cause an overflow in 8-bit embedded systems?

在下面的示例中,“a + b”将溢出两个变量的大小。这个临时结果会存储在 16 位 space 还是需要的最大位?

这种情况是否跨编译器标准化? 系统架构重要吗?我在一个 8 位微控制器上。短类型为 16 位。

res 等于 50000、17232 还是未定义?

unsigned short a = 50000;
unsigned short b = 50000;
unsigned short res = 0;

void main()
{
    res = (a + b) / 2;
}

严格来说,无符号类型不会溢出,而是“环绕”,这是定义明确的行为,但可能是意想不到的。正式的例子见C标准C17 6.2.4/9:

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

为了完全理解这些东西,您需要从 开始。许多 C 表达式中都发生了各种隐含和微妙的事情。

在这种特殊情况下,不太可能有任何隐式转换,因为 unsigned short 在任何已知的 8 位系统上都是 16 位,int 也是如此。在这种情况下,unsigned short 只是转换为 unsigned int,两者都是 16 位。

因为它是无符号类型,C 标准保证 环绕并产生值 34464,这意味着最终结果保证在所有情况下都变为 17232现实世界中的 8 位和 16 位系统。如果类型已签名,则不会有任何保证,但会因为溢出而出现未定义的行为。


总结一下:

Will this temporary result be stored in a 16-bit space or the biggest needed?

16 位 space 因为只有(可能提升的)操作数的类型很重要。

Is this situation standardized across compilers?

是的,对于无符号类型,代码在 8 位和 16 位系统上是 100% 可移植的。这是C标准保证的。

Does the system architecture matter?

是的,int 的大小对于决定是否推广某物很重要。在 8 位和 16 位上,int 实际上总是 16 位(尽管理论上 C 允许它是其他东西)。在 32 位和 64 位上,它实际上始终是 32 位。

Is res equal to 50000, 17232, or undefined?

8 位和 16 位系统为 17232,32 位和 64 位系统为 50000。