Search code examples
gccclangcompiler-optimizationllvm-gcclto

Inline functions and link time optimizations


I am trying to study the effects of inlining and link-time optimization currently I am trying to link two files with one of them having an explicit inline function call

below are the files:

test.c

void show(int *arr,int n ){

  for(int i=0;i<n;i++)
printf("%d",arr[i]);
 
}


int main(){

  int arr[10]={0};
  foo(arr);

}

test1.c

inline void foo(int *arr){
 
   show(arr,10);
}

so I am trying to compile them as

gcc -c -O2 -flto test.c
gcc -c -O2 -flto test1.c
gcc -o myprog -flto -O2 test1.o test.o

but this still gives a linker error as in undefined reference to foo in main

Did I compile it correctly? Is gcc failing to inline?

Any help would be appreciated


Solution

  • From C11 6.7.4p7 emphasis mine:

    Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition

    Your code is does not provide a definition of foo with external linkage and compiler is right - there is no foo. The foo in test1.c is an inline function, it doesn't provide a function with external definition.

    Did I compile it correctly?

    Well, yes.

    Is gcc failing to inline?

    The compilation failed, so yes.

    The keyword inline may serve as a hint for the compiler to maybe inline the function. There is no requirement that compiler will do that. inline is a misleading keyword - it serves primarily to modify linkage of objects, so to let the compiler choose between inline and non-inline versions of the same function available within the same transaction unit. It does not mean that the function will be inlined.

    If you are using LTO, just drop the inline, there is no point in hinting the compiler - trust gcc it will do a better job optimizing then you will, with LTO it "sees" all the functions in single transaction unit anyway. Also read gcc docs on inline and remember about the rules of optimization.