Будет ли g cc понимать, что c является одним и тем же постоянным значением для всех рекурсивных вызовов, а затем будет использовать одну и ту же переменную для всех вызовов, или он скопирует значение c в new c переменная каждый вызов?
В этом конкретном случае g cc видит, что значения никогда не используются разумным способом. На x64 gcc -Os -S file.c
генерирует следующий код сборки (file.s
, для краткости вырезаны нерелевантные детали):
rec_func:
.L2:
jmp .L2
Таким образом, вы должны использовать более разумный пример. g cc попытается преобразовать рекурсивные вызовы в циклы, например для
int rec_func (int a, int b, const int c)
{
return a == b
? c + a
: 1 - rec_func (a - c, b, c);
}
, снова скомпилированные с -Os
(компиляция для скорости также не будет использовать рекурсию, конечно)
rec_func:
movl $1, %ecx
xorl %eax, %eax
.L3:
cmpl %esi, %edi
je .L5
addl %ecx, %eax
subl %edx, %edi
negl %ecx
jmp .L3
.L5:
addl %edx, %edi
imull %ecx, %edi
addl %edi, %eax
ret
Нет вызова / перейти к rec_func
в любом месте. Даже с c + 1
в качестве третьего аргумента сгенерированный код будет только на одну инструкцию длиннее.
поймет ли g cc, что это неявно const?
Да. Что касается const
в const c
, это ничего не меняет; любой реальный компилятор, подходящий для практических целей, сам определит, что c
никогда не изменится. Текущий случай const
является для вас только напоминанием о том, что c
доступен только для чтения, и вы не измените его.