Why does gcc not add tmin + tmin correctly?

-1

I've been playing around with bitwise operations and two's complement, when I discovered this oddity.

#include <stdio.h>
int main ()
{
    int tmin = 0x80000000;
    printf("tmin + tmin: 0x%x\n", tmin + tmin);
    printf("!(tmin + tmin): 0x%x\n", !(tmin + tmin));
}

The code above results in the following output

tmin + tmin: 0x0
!(tmin + tmin): 0x0

Why does this happen?

c
gcc
twos-complement
asked on Stack Overflow Oct 9, 2019 by Don Thousand • edited Oct 9, 2019 by Don Thousand

1 Answer

1

0x80000000 in binary is

0b10000000000000000000000000000000

When you add two 0x80000000s together,

    |<-          32bits          ->|
  0b10000000000000000000000000000000
+ 0b10000000000000000000000000000000
------------------------------------
 0b100000000000000000000000000000000
    |<-          32bits          ->|

However, int on your machine seem to have 32 bits, so only the lower 32 bits are preserved, which means the 1 in your result is silently discarded. This is called an Integer Overflow.

Also note that in C, signed (as opposed to unsigned, i.e. unsigned int) integer overflow is actually undefined behavior, which is why !(tmin + tmin) gives 0x0 instead of 0x1. See this blog post for an example where a variable is both true and false due to another undefined behavior, i.e. uninitialized variable.

answered on Stack Overflow Oct 9, 2019 by nalzok • edited Oct 10, 2019 by nalzok

User contributions licensed under CC BY-SA 3.0