Compiler optimization causing strange behavior with bit-wise shifts

1

Disclaimer, this is about shift overflows which I know gives undefined behavior; so this really shouldn't be a question. The reason I am asking this is for my curiosity.

Here is my code.

test.c:

#include <stdio.h>

void func(int val)
{
    int allOnes = 0xffffffff;

    printf("0x%x << 32  = 0x%x\n", allOnes, allOnes << 32);
    printf("0x%x << val = 0x%x\n", allOnes, allOnes << val);
}

int main()
{
    func(32);
}

When I run this with no compiler optimizations (gcc -O0 -Wall -g test.c -o test.o) I get the following.

0xffffffff << 32  = 0xffffffff
0xffffffff << val = 0xffffffff

However, when I run this with compiler optimizations (gcc -O1 -Wall -g test.c -o test.o) I get the following.

0xffffffff << 32  = 0x0
0xffffffff << val = 0xffffffff

My question is: what causes this?

EDIT: More specifically, why is there a discrepancy between running with compiler optimization and without?

c
gcc
compiler-optimization
bit-shift
asked on Stack Overflow Jan 12, 2020 by Zack Jorquera • edited Jan 12, 2020 by Zack Jorquera

1 Answer

2

I did some digging and I found when you use compiler optimizations (-O1), the compiler replaces the shift operation with its "result". In the assembly, there is a mov edx, 0 as opposed to a shl edx, 32.

The discrepancy here is just due to the processor and the compiler having different results. It is undefined behavior after all.

answered on Stack Overflow Jan 12, 2020 by Zack Jorquera

User contributions licensed under CC BY-SA 3.0