Question: I'm reading chapter 7 of [C programming: a modern approach](http://knking.com/books/c2/index.html), and a bit unclear how `printf` handles type conversion.

Consider the following code:

```
int main() {
    int i = 47000; // This will overflow when squared

    int i2 = square(i);

    long l = square(i);

    printf("i2 = %ld, l = %ld, i * i = %ld, square(i) = %ld",
       i2, l, i * i, square(i));

    return 0;
}

int square(int i) {
    int j = i * i;
    return j;
}

```

I expected the output to be (due to overflowing):

```
i2 = -2085967296, l = -2085967296, i * i = -2085967296, square(i) = -2085967296

```

But instead I got:

```
i2 = 2209000000, l = -2085967296, i * i = 2209000000, square(i) = 2209000000

```

Could you explain:

a) why some results didn't overflow?

b) why `l` overflowed?

Answer: 
You get undefined behavior using `%ld` to print `int`s. 

What you are actually seeing is an artifact of the X86-64 parameter passing.

When you explicitly convert the `int` value returned by `square` from 32 bit to 64 bit `long`, you sign extend, preserving the overflow. So that one shows the expected overflow. 

The first few `int`s passed to a function in x86-64 are zero extended to 64-bits (later ones may be garbage extended). That should be an invisible effect, because only the low 32-bit should be used. But then you used `%ld` causing all 64 bits to be used. The particular value had overflowed in a way that causes zero extension to 64-bit to accidentally get back to the non overflowed value. 

So the undefined behavior of passing an `int` that the receiving function aliases as `long` accidentally undid the overflow.
`printf` doesn't do type conversions. It takes its arguments (other than the format string) through an ellipsis, so it has to trust the format string to tell it what the types of the input values are.

`"%ld"` tells `printf` that the corresponding value has type `long int`. The values of `i2`, `i * i`, and `square(i)` all have type `int`. So the format specifier is wrong, and the displayed values are nonsense. Use `"%d"` for `int`.