priyanka priyanka - 13 days ago 5x
C Question

Why printf shows wrong value for int variable for different compiler settings 64 vs 32?

I have following program.

int main () {
int a = 1;
long long b = 100000000;
printf("size of a is: %d \t sizeof b is:%d \n",sizeof(a),sizeof(b));
printf("a= %d b=%d a=%d \n", a, b, a);
printf("a= %d b=%Ld a=%d \n", a, b, a);
b = 10000000000;
printf("a= %d b=%d a=%d \n", a, b, a);
printf("a= %d b=%Ld a=%d \n", a, b, a);

When I compile it with
gcc -m32
output is

size of a is: 4 sizeof b is:8
a= 1 b=100000000 a=0
a= 1 b=100000000 a=1
a= 1 b=1410065408 a=2
a= 1 b=10000000000 a=1

but when it is compiled with
gcc -m64
output is.

size of a is: 4 sizeof b is:8
a= 1 b=100000000 a=1
a= 1 b=100000000 a=1
a= 1 b=1410065408 a=1
a= 1 b=10000000000 a=1

Why does it show wrong values while printing third printf argument (a)?

My gcc version is

priyanka@priyanka-N551JB:~$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu


You must print long long values using %lld. You cannot print them using %d. If you try to print them using %d it won't work.

The number 10000000000 requires 34 bits to represent it. As you've discovered, it will not fit in a 16-bit or 32-bit plain int. However, it will fit in a 64-bit long long int.

It's difficult to know exactly what happens when you try to print a 64-bit long long using %d. You can imagine that 8 bytes get pushed on the stack, and %d pops 4 of them off. Therefore, the other four are still left on the stack, so they're what gets popped for the third %d, not a's actual value. This isn't necessarily exactly what happens, in actuality it's likely to be more complicated than that. And the complications might very easily depend on whether you're compiling in 32 or 64 bit mode.

This ends up being a small, simple illustration of an important point: when a program uses undefined behavior, all aspects of the program become undefined. When you do something really wrong, like trying to print b's long long value using %d, what goes wrong is not only that b's value is printed improperly -- other things go wrong, too.

Here's an analogy. Suppose you buy a brand-new racing bicycle with thin, fast tires. The salesman reminds you that it's a road bike, for riding on smooth paved roads only. If you try to ride it off-road, the salesman warns you, the tires are likely to pop if you hit a rock.

Now, suppose you do ride the bike off the road. And suppose you hit a rock, and the tire pops, and you lose control, and crash, and bend the handlebars, and also get a cut on your forehead. Suppose you go back to the bike shop and say, "Okay, I rode the bike off the road, and the tire popped like you said. But can you explain why the handlebars got bent, and I got this cut on my head?"