The following code,
int foo(int);
int bar(int);
int foobar(int i) {
int a = foo(i);
int b = bar(i);
return a == b ? a : b;
};
with GCC trunk is compiling to this assembly:
foobar(int):
push rbx
mov ebx, edi
call foo(int)
mov edi, ebx
pop rbx
jmp bar(int)
Here is it live.
This TU has no clue what i it will be given, and it has no clue what foo and bar will return, so it has no clue whether a == b will be true or false. So it must
inspect the outputs of the two calls and somehow compare them to decide which one it shuld return.
But I can't see that in the assembly. What am I missing?
return a == b ? a : b; is same as return a == b ? b : b; is same as return b;.
Consider the two cases:
(1) a is equal to b.
Then foo(i) and bar(i) must be invoked in this order. The code does so. Since the return value of bar(i) is the same as that of foo(i), it is sufficient to call bar in a tail call and let it's result return to the caller of foobar.
(2) a is not equal to b.
Then foo(i) and bar(i) must be invoked in this order. The code does so. Since the return value of bar(i) is different from that of foo(i), b, i.e., the return value of bar(i) must be returned to the caller. This can be achieved by a tail call of bar and let it's result return to the caller of foobar.
The two cases do exactly the same thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With