In the example below "a + b" will overflow the size of both variables. Will this temporary result be stored in a 16-bit space or the biggest needed?
Is this situation standardized across compilers? Does the system architecture matter? I'm on an 8-bit microcontroller. Short type is 16-bit.
Is res equal to 50000, 17232, or undefined?
unsigned short a = 50000;
unsigned short b = 50000;
unsigned short res = 0;
void main()
{
res = (a + b) / 2;
}
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.