Home > Enterprise >  Do inlined pass-by-reference functions still create reference variables?
Do inlined pass-by-reference functions still create reference variables?

Time:03-06

I am writing a loop that has some state variables.

int MyFunc(){
    int state_variable_1 = 0;
    int state_variable_2 = 12;

    while(state_variable_1 != state_variable_2){
        BodyOfWhileLoop(state_variable_1, state_variable_2);
    }
}

As you can see, I have written the body of the while loop in a separate function, BodyOfWhileLoop. This is to keep the code clean and to aid in debugging.

BodyOfWhileLoop will need to modify state_variable_1 and state_variable_2. I could pass these by reference, for example,

void BodyOfWhileLoop(int& state_variable_1, int& state_variable_2);

This is functionally exactly what I want, however, each use of the state variables in the body of the function requires a dereference (I believe). I could do something like this:

void BodyOfWhileLoop(int& state_variable_1_ref, int& state_variable_2_ref){
    int state_variable_1_copy = state_variable_1_ref; 
    int state_variable_2_copy = state_variable_2_ref; 

    // Do stuff with state variables
    
    state_variable_1_ref = state_variable_1_copy; 
    state_variable_2_ref = state_variable_2_copy; 
}

I see two things to be true:

  1. Copying the state variables costs memory since you allocate space for the copy.
  2. Not copying the state variables will cost time because there is an extra dereference in the body of BodyOfWhileLoop each time you access the state variable.

So I have two questions:

  1. If the compiler inlined BodyOfWhileLoop, would it still create a state_variable_1_ref and state_variable_2_ref (requiring a dereference to access the ints)? Would the cost of accessing state_variable_1 be the same as accessing it within MyFunc?
  2. Are there alternative solutions I have not seen?

CodePudding user response:

No, they do not. Demonstration: https://godbolt.org/z/qc1ne7ezM.

References are typically implemented as pointers under the hood (though they do not have to be). Once the function is inlined the compiler will eliminate the indirection. In LLVM, this optimization is performed as part of SROA.

Any function with only one callsite should be inlined by the optimizer but note that if a function has external linkage the compiler may not inline it: It could be used in other translation units so the compiler doesn't know it's only used once. To avoid this, mark it static or inline, or use link-time optimization.

CodePudding user response:

The C standard does not require the C compiler to produce the compiled code in any particular way. The C standard specifies the results of well-formed C code, and how the compiler goes about doing that is entirely up to the compiler. No two C compilers are alike, and different C compilers are likely to take different approaches and produce different compiled code from a C program of moderate complexity.

Furthermore, more and more C compilers have evolved to implement new link-time optimization techniques which extend the scope of possible optimizations beyond what was traditionally possible, up to this point.

In general, C compilers are permitted to implement any optimization that has no observable effect. If your C compiler can prove to itself that the optimization you contemplated has no observable effect, then your C compiler can (but is not obligated) to implement it.

Whether or not a compiler ends up making this, or any other, optimization is entirely up to the compiler, and the end results may be different depending on compilation options, too. So, there is no definitive answer to a question of this sort, except to compile the code and then inspect the resulting compiled machine code to see what your compiler dir.

  • Related