Вам может показаться интересным, что с 5.4 функция не полностью исключена, для этого вам нужно как минимум 6.1.
Я не думаю, что происходит кэширование. Я убежден, что оптимизатор достаточно умен, чтобы доказать связь между fib(n - 2)
и fib(n-1)
и полностью избежать второго вызова. Это вывод G CC 5.4 (полученный из godbolt) без constexpr
и -O2:
fib(long):
cmp rdi, 1
push r12
mov r12, rdi
push rbp
push rbx
jle .L4
mov rbx, rdi
xor ebp, ebp
.L3:
lea rdi, [rbx-1]
sub rbx, 2
call fib(long)
add rbp, rax
cmp rbx, 1
jg .L3
and r12d, 1
.L2:
lea rax, [r12+rbp]
pop rbx
pop rbp
pop r12
ret
.L4:
xor ebp, ebp
jmp .L2
Я должен признать, что не понимаю вывод с -O3 - сгенерированный код на удивление сложный, с большим количеством обращений к памяти и арифметикой указателей, и вполне возможно, что с этими настройками выполняется некоторое кэширование (запоминание).