On 09/02/2023 13:11, Vir Campestris wrote:
> On 07/02/2023 20:00, Keith Thompson wrote:
>> It seems to me the author encountered a compiler bug, not a flaw in the
>> language.
>
> That was my first thought. but then I read on...
>
> On 07/02/2023 22:16, David Brown wrote:
> > It would also be fine for the compiler to pre-calculate fib(42) at
> > compile time and skip the run-time calculation entirely.
>
> And that also seemed quite possible. So I looked at his stuff on
> Godbolt. It's clearly making two calls to now(), passing an address on
> the stack in eax to both calls.
>
> Only then does it call fib(). The odd thing is that the parameter to
> fib() is on the stack - and it calls fib() twice with values 41 and 40,
> then adds the two results together.
>
> It then does something with cout I can't be bothered to decode.
(When looking at this kind of stuff, I usually remove any main, cout or
printf nonsense and replace them with calls to a simple extern function
that is never defined. Then the generated assembly code is vastly
easier to understand.)
>
> I don't understand why it adds fib for 40 and 41 together either,
> instead of just calling it with 42.
>
It is inlining the first call to fib(42), to get fib(41) + fib(40).
That too is a perfectly valid optimisation (and the two fib's can be
called in either order). It is not necessarily a particularly helpful
optimisation, but it is valid.
> I'll go with compiler bug.
>
I disagree.
Again, you can happily argue that the transformations made here are not
helpful, but I cannot see that any are invalid.
It all comes down to observable behaviour. The calls to "now()" are
observable, and must be done in the order specified in the code. The
outputs to cout is also observable, and must be ordered correctly with
respect to the calls to "now()". The call(s) to "fib" are not
observable, and can be moved around freely or eliminated entirely as
long as the result is known before it is used in the "cout" output.