Why are these two versions of code different? I had been under the impression that unsigned integer overflow is well-defined in C and that if you have uint16_t a,b
then a-b
has a result type of uint16_t
.
#include <stdint.h>
uint32_t frobnicate1(uint32_t prevsum, uint16_t command, uint16_t response)
{
uint32_t error = command-response;
return prevsum + error;
}
uint32_t zoop1()
{
return frobnicate1(0, 30001, 30002);
}
uint32_t frobnicate2(uint32_t prevsum, uint16_t command, uint16_t response)
{
uint16_t error = command-response;
return prevsum + error;
}
uint32_t zoop2()
{
return frobnicate2(0, 30001, 30002);
}
But zoop1()
returns -1 (not expected!!!) whereas zoop2()
returns 65535 (expected).
When I see command-response
and the result is -1 modulo 65536 = 65535, and is supposed to have type uint16_t
, I'm wondering why the compiler is allows to promote 65535 to -1 when going to uint32_t
.
(Tried on godbolt.org with x86-64 gcc and clang -O2 -Wall
)