首页 > 解决方案 > 临时操作会导致 8 位嵌入式系统溢出吗?

问题描述

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

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

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

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

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

标签: cembedded8-bit

解决方案


Strictly speaking, unsigned types do not overflow but "wrap-around", which is well-defined behavior but perhaps unexpected. Formally see for example the C standard 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.

In order to fully understand these things you need to start with Implicit type promotion rules. There are various implicit and subtle things going on in many C expressions.

In this particular case, there are unlikely any implicit conversions because unsigned short is 16 bits on any known 8-bit system, and so is int. In this case the unsigned short is merely converted to unsigned int, both are 16 bit.

Since it's an unsigned type, it is guaranteed by the C standard to wrap-around and yield the value 34464, meaning that the end result is guaranteed to become 17232 on all 8- and 16-bit systems in the real world. Had the types been signed, there would be no guarantees but undefined behavior because of overflow.


To summarize:

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

16 bit space since only the types of the (potentially promoted) operands matter.

Is this situation standardized across compilers?

Yes, in case of unsigned types the code is 100% portable across 8- and 16 bit system. This is guaranteed by the C standard.

Does the system architecture matter?

Yes, the size of int matters in determining whether something is promoted or not. On 8- and 16 bitters, int is always de facto 16 bits (though in theory C allows it to be something else). On 32 and 64 bitters it is always de facto 32 bits.

Is res equal to 50000, 17232, or undefined?

17232 on 8- and 16 bit systems, 50000 on 32- and 64 bit systems.


推荐阅读