1

Given the following function:

void rec_func(int a, int b, const int c) {
    /*
        flow control and stuff here
    */
    rec_func(a - 1, b, c);
}

Will gcc understand that c is the same constant value for all the recursive calls and then will use the same variable for all the calls, or it will copy the value of c to a new c variable each call?

The same question for b, even if not marked with const, will gcc understand that is implicitly const?

Edit1:
The question is made from an optimization perspective

Edit2:
By "implicitly const" I do not mean some keyword. I mean, a variable not tagged with the const modifier whose value will never change once initialized.

6
  • The answer is the same, whether it involves recursion or not Commented Feb 24, 2020 at 17:07
  • "implicitly const" is not a thing! If it's const, the compiler won't let you change it; if it's not, you can. Commented Feb 24, 2020 at 17:15
  • What's not clear is your motivation for the question. Commented Feb 24, 2020 at 17:15
  • 1
    gcc's optimizer will convert this recursive call into a loop. Commented Feb 24, 2020 at 17:42
  • 1
    @EddInglis: “Implicitly const” is a thing; compilers generally are able to recognize some, perhaps many, invariants and optimize accordingly. Commented Feb 24, 2020 at 18:00

2 Answers 2

2

My guess is that you're coming at this from an optimization perspective.

If that's the case:

  1. Don't worry about it; the compiler is much smarter than you* and will do a good job.
  2. Recursion is rarely 'optimal' performance-wise.

If you don't try to alter b or c in your control logic, the compiler might do something clever, but passing around an int is not likely to be a big problem. If you were passing around a giant structure, then you might consider using a pointer or reference instead.

Anyway, you can see what GCC is going to do with the amazing godbolt tool.

But as I said in my comment, it's not clear what the motivation for your question is, so I might be far wide of the mark with my answer.

[*] Not you specifically!

Sign up to request clarification or add additional context in comments.

2 Comments

Aside: compilers often pass the first few parameters in registers, so there would be no need to copy them between calls anyway.
Very useful the godbolt tool! Thanks
1

Will gcc understand that c is the same constant value for all the recursive calls and then will use the same variable for all the calls, or it will copy the value of c to a new c variable each call?

In this particular case, gcc sees that the values are never used in a sensible way. On x64, gcc -Os -S file.c generates the following assembly code (file.s, snipped irrelevant parts for brevity):

rec_func:
.L2:
    jmp .L2

Thus you should use some more sensible example. gcc will try to transform recursive calls to loops like for

int rec_func (int a, int b, const int c)
{
    return a == b
        ? c + a
        : 1 - rec_func (a - c, b, c);
}

again compiled with -Os (compiling for speed will not use recursion either, of course)

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

No call / jump to rec_func anywhere. Even with c + 1 as 3rd argument, the generated code is only one instructions longer.

will gcc understand that is implicitly const?

Yes. As for the const in const c, this does not change anything; any real-world compiler suitable for practical purposes will determine on its own that c will never be changed. The the present case const is just a reminder for you that c is read-only and you won't change it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.