我试图在线搜索一个好的答案,但没有得到一个我完全可以理解的答案。假设我有一个标题" add.h":
inline int add(int a, int b){ return a+b; }
一个名为" adddouble.c":
的文件#include "add.h"
int adddouble(int a, int b){ return 2*add(a,b); }
一个名为" addsquare.c":
的文件#include "add.h"
int addsquare(int a, int b){ return add(a,b)*add(a,b); }
主文件" main.c":
#include<stdio.h>
int adddouble(int, int);
int addsquare(int, int);
int main(){
printf("add double = %d\n", adddouble(10,20));
printf("add square = %d\n", addsquare(10,20));
return 0;
}
我使用gcc5.2.0来编译这些文件,但得到了:&#34;架构x86_64的未定义符号:&#34;。如果我在add.h或中添加静态到内联函数 add declaration&#34; extern int add(int,int);&#34; to&#34; adddouble.c&#34;,它编译 成功没有错误。我是内联函数的新手,我不知道如何解释和理解这种行为。感谢
答案 0 :(得分:7)
根据 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf, 看起来内联函数在C和C ++中的行为有所不同:
任何具有内部链接的函数都可以是内联函数。为一个 具有外部链接的功能,以下限制适用:如果a 函数用内联函数说明符声明,然后它应该 也可以在同一个翻译单元中定义。如果所有的文件范围 翻译单元中的函数声明包括内联 没有extern的函数说明符,那么其中的定义 翻译单元是内联定义。内联定义可以 没有为函数提供外部定义,也没有 禁止在另一个翻译单元中使用外部定义。内联 定义提供了外部定义的替代方案,其中a 翻译器可以用来实现对该功能的任何调用 翻译单位。未指定是否调用该函数 使用内联定义或外部定义。 140)
如果你没有把static
放在那里,你就是在没有实例化外部定义的情况下定义一个带有外部链接的内联函数。
extern int add(int, int);
实例化该函数的外部定义,您需要完成一次(在哪个文件中无关紧要)才能使链接成功(或者您可以标记内联函数{{1}并且问题消失了。
(在C ++中,static
在每个翻译单元中创建弱外部定义,因此您不必担心标记事物inline
或仅实例化一个外部定义内联函数 - g ++应该直接用static
编译它,没有任何问题。)