内联函数和链接时间优化

问题描述

我正在尝试研究内联和链接时间优化的影响,目前我正在尝试链接两个文件,其中一个文件具有显式的内联函数调用

以下是文件

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);
}

所以我试图将它们编译为

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

但是这仍然会产生链接错误,就像在main中对foo的未定义引用中一样

我编译正确了吗? gcc无法内联吗?

任何帮助将不胜感激

解决方法

摘自C11 6.7.4p7我的重点:

任何具有内部链接的函数都可以是内联函数。为一个 具有外部链接的功能,则存在以下限制:如果 用内联函数说明符声明函数,然后应 也可以在同一翻译单元中定义。如果所有文件范围 翻译单元中函数的声明包括内联 不带extern的函数说明符,则其中的定义 翻译单元是内联定义。 内联定义可以 没有为函数提供外部定义,并且没有 禁止在另一个翻译单元中使用外部定义。内联 定义提供了外部定义的替代方法, 转换器可以用来在同一位置实现对该函数的任何调用 翻译单位。未指定是否调用该函数 使用内联定义或外部定义

您的代码没有提供带有外部链接的foo的定义,并且编译器正确-没有foofoo中的test1.c是内联函数,它不提供具有外部定义的函数。

我编译正确了吗?

好吧。

gcc是否无法内联?

编译失败,所以是。

关键字inline 可以用作提示,供编译器可能内联该函数。不需要编译器执行此操作。 inline是一个具有误导性的关键字-它主要用于修改对象的链接,以便让编译器在同一事务单元中可用的同一功能的内联和非内联版本之间进行选择。这并不意味着该函数将被内联。

如果您使用的是LTO,请直接插入内联,提示没有意义-信任gcc会比LTO更好,优化效果会更好无论如何,“查看”单个交易单元中的所有功能。还要阅读gcc docs on inline,并记住有关rules of optimization的信息。