Reputation: 111
I just tried to lower a unsigned int below 0. To my surprise it works!
#include<stdio.h>
int main(void)
{
unsigned int foo = 5;
foo -= 10;
printf("%d", foo);
return 0;
}
Compiled with
clang -Weverything main.c
This program returnes
-5
As this post and my personal knowledge states, it's not possible. But why does it work then? Am i missing something? Is it because of Undefined Behavior? Or is it printf? Or something else?
Upvotes: 4
Views: 1602
Reputation: 104
Numbers on computers are stored in two's complement form. And a negative number represented in 2's complement is valid number in unsigned number's range. A processor core is cleverly implements addition/subtractions/multiplication/division such that it does not need to know the sign of the numbers to perform these operations. C language which make use of this core passed these numbers to arithmetic unit of processor which do the requested operation and return the result. That's why you got the result as expected on integers.
Upvotes: 0
Reputation:
printf() is interpreting the value of foo as a signed integer. Try replacing %d with %u.
Edit: As dasblinkenlight said, this is undefined behavior. The programming language specification does not say what should be done if this happens, so it is left up to the implementation. Sometimes this may yield a different result, but in this case, it probably won't.
Upvotes: 4
Reputation: 726579
This program uses printf
to re-interpret an unsigned int
's value as a signed integer. Although this is not a problem when the value of unsigned int
also fits in an int
, it is undefined behavior:
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined
Explanation: Subtracting ten from five "wraps around", so you get a large number based on your system's representation of unsigned int
. It turns out that the bit representation of this large number corresponds to representation of negative five on your system, so when printf
reinterprets the value as signed, negative five gets printed.
why isn't there any notice from compiler?
See this Q&A for a possible explanation.
Upvotes: 6