Why is gcc-multilib output incorrect for bitwise operation?

4

bug.c

#include <stdio.h>

int main()
{
    int x = 0x7fffffff;
    printf("%x\n", x);
    printf("%x\n", ~x);
    printf("%x\n", ~x + ~x);
    printf("%x\n", !(~x + ~x));
}

I compile using gcc -m32 bug.c -o bug This outputs:

7fffffff
80000000
0
0

It should output

7fffffff
80000000
0
1

I am using gcc 9.3 and gcc-multilib on Ubuntu 20.04. I have also tested this with gcc8 and gcc10. The output was correct when I used clang. Does anyone have any idea why this is happening?

c
gcc
bit-manipulation
undefined-behavior
integer-overflow
asked on Stack Overflow Feb 24, 2021 by wdslau • edited Feb 25, 2021 by phuclv

2 Answers

4

Enable all warnings and undefined behavior sanitizer with the -Wall -Wextra -pedantic -fanalyzer -fsanitize=undefined options and you'll see that gcc outputs this error

example.cpp:8:11: runtime error: signed integer overflow: -2147483648 * 2 cannot be represented in type 'int'

You can also specify more sanitizers like this -fsanitize=signed-integer-overflow,leak,undefined,address

See demo on Compiler Explorer. Notice that Clang also reports UB:

example.cpp:8:23: runtime error: signed integer overflow: -2147483648 + -2147483648 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior example.cpp:8:23 in 
example.cpp:9:25: runtime error: signed integer overflow: -2147483648 + -2147483648 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior example.cpp:9:25 in 
answered on Stack Overflow Feb 25, 2021 by phuclv
1

That's signed integer overflow which is technically UB, although I'm surprised somebody managed to observe it with bitbashing. Usually that's weird loop bounds behaviors. If you want weird bit operations to work, use unsigned int, which is specified to wrap.

answered on Stack Overflow Feb 24, 2021 by Joshua

User contributions licensed under CC BY-SA 3.0