Paul Kramme
Paul Kramme

Reputation: 111

Why is a unsigned int below zero possible?

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

Answers (3)

Ashwani
Ashwani

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

user6557303
user6557303

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Related Questions