Search code examples
c++pass-by-referencecompiler-optimizationstatic-variables

Optimizing away static variable / passing by reference


In this question Will a static variable always use up memory? it is stated that compilers are allowed to optimize away a static variable if the address is never taken, e.g. like following:

void f() {
   static int i = 3;
   printf( "%d", i );
}
  1. If there exists a function which takes its arguments by reference, is the compiler still allowed to optimize away the variable, e.g. as in
void ref( int & i ) {
    printf( "%d", i );
}
void f() {
   static int i = 3;
   g( i );
}
  1. Is the situation different for the "perfect forwarding" case. Here the function body is empty on purpose:
template< typename T >
void fwd( T && i ) {
}
void f() {
   static int i = 3;
   fwd( i );
}
  1. Furthermore, would the compiler be allowed to optimize the call in the following case. (The function body is empty on purpose again):
void ptr( int * i ) {
}
void f() {
   static int i = 3;
   ptr( &i );
}

My questions arise from the fact, that references are not a pointer by the standard - but implemented as one usually.

Apart from, "is the compiler allowed to?" I am actually more interested in whether compilers do this kind of optimization?


Solution

  • that compilers are allowed to optimize away a static variable if the address is never taken

    You seem to concentrated on the wrong part of the answer. The answer states:

    the compiler can do anything it wants to your code so long as the observable behavior is the same

    The end. You can take the address, don't take it, calculate the meaning of life and calculate how to heal cancer, the only thing that matters is observable effect. As long as you don't actually heal cancer (or output the results of calculations...), all calculations are just no-op.

    f there exists a function which takes its arguments by reference, is the compiler still allowed to optimize away the variable

    Yes. The code is just putc('3').

    Is the situation different for the "perfect forwarding" case

    No. The code is still just putc('3').

    would the compiler be allowed to optimize the call in the following case

    Yes. This code has no observable effect, contrary to the previous ones. The call to f() can just be removed.

    in whether compilers do this kind of optimization?

    Copy your code to https://godbolt.org/ and inspect the assembly code. Even with no experience in assembly code, you will see differences with different code and compilers.

    Choose x86 gcc (trunk) and remember to enable optimizations -O. Copy code with static, then remove static - did the code change? Repeat for all code snippets.