0

I ran into an interesting scenario with integer conversion:

#include <stdio.h>

int main()
{
    unsigned int x = 20;
    unsigned int y = 40;

    printf("%d\n", x - y);
    printf("%d\n", (x - y) / 4);
}

~ % ./a.out
-20
1073741819

I wasn't expecting the 2nd result. Since x and y are both unsigned ints is the result of x - y unsigned (and in this case displayed as signed by printf)?

jmq
  • 1,559
  • 9
  • 21
  • "is the result of x - y unsigned" Yes. Try `x - y < 0` – MikeCAT Jun 01 '22 at 23:12
  • You can also try `char * p = x - y;` and look carefully at the error message of the compiler when it complains about an invalid conversion. – David Grayson Jun 01 '22 at 23:15
  • 2
    The argument corresponding to `%d` should be `int`. To print `unsigned int` use `%u`. – Barmar Jun 01 '22 at 23:18
  • The first printf could have shown `-2147483628` if you had one's-complement. It's the conversion from unsigned to signed inside printf that is a problem and implementation defined. – Goswin von Brederlow Jun 01 '22 at 23:21

1 Answers1

1

The things you are printing are indeed unsigned integers and you should print them with %u, but that does not explain the surprising result for the second number. The surprising result comes from an overflow occurring when you calculate x - y, since the result of that subtraction is negative and thus not representable as an unsigned int.

Unsigned overflow/underflow is not undefined behavior, so it's OK to have code like this in production if you know what you are doing.

David Grayson
  • 84,103
  • 24
  • 152
  • 189