【问题标题】:Inline function in header file in C [duplicate]C中头文件中的内联函数[重复]
【发布时间】:2016-03-12 10:04:27
【问题描述】:

我试图在网上搜索一个好的答案,但没有找到一个我能完全理解的答案。假设我有一个标题“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 编译这些文件,但得到:“架构 x86_64 的未定义符号:”。如果我将静态添加到 add.h 中的内联函数或 添加声明“extern int add(int, int);”到“adddouble.c”,它编译 成功没有错误。我是内联函数的新手,我不知道如何解释和理解这种行为。谢谢

【问题讨论】:

  • 您有哪些构建选项?除非您在 C99 或 C11 中构建,否则 C 中没有内联函数的概念。
  • 头文件必须和其他c文件一起编译或者同时提供.h和.c,add的原型为add.h,代码为add.c
  • +1 好问题。它实际上与 g++ 链接得很好,但我无法让它与 gcc (-std=c11) 一起使用。这些添加符号在 addsquare.o 和 adddouble.c 中都是未定义的 (U)。 g++ 反而为 add 函数创建了弱符号 (W),这就是它链接的原因。
  • 加上-std=c99,还是不行。
  • 见这个:C99 inline function in .c file。您必须为 add() 提供外部定义。

标签: c inline


【解决方案1】:

根据 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf, 看起来 内联 函数在 C 和 C++ 中的行为不同:

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

如果您没有将static 放在那里,那么您将定义一个具有外部链接的内联函数,而无需实例化外部定义。

extern int add(int, int); 为该函数建立外部定义,您需要只执行一次(在哪个文件中无关紧要)才能成功链接(或者您可以标记内联函数 static 和问题消失)。

(在 C++ 中,inline 在每个翻译单元中创建 weak 外部定义,因此您不必担心标记事物 static 或为内联函数仅实例化一个外部定义 - -g++ 应该直接用for f in *.c; do g++ -c "$f"; done; g++ *.o 编译它,没有任何问题。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多