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?
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.