使用-std = gnu99和内联函数时编译错误

时间:2012-10-05 13:22:31

标签: c gcc

以下代码:

#include <stdio.h>
inline int myfunc (int x) {
    return x+3;
}

int main () {

    printf("%d", myfunc(2));
    return 0;
}
当我使用-std=gnu99标志(我正在使用gcc编译)时,

无法编译。这是它抛出的错误:

gcc -std=gnu99 -c main.c -o main.o
gcc -std=gnu99 main.o -o main
main.o: In function `main':
main.c:(.text+0x15): undefined reference to `myfunc'
collect2: ld returned 1 exit status
make: *** [main] Error 1

当省略-std=gnu99时,编译没有问题。有没有人知道如果使用-std=gnu99链接器为什么会抱怨?

4 个答案:

答案 0 :(得分:8)

在C99中,您需要为内联函数指定声明,如

int myfunc(int);

或允许编译器通过指定-finline-functions-O3来实际内联函数。

引用C99标准:

  

任何具有内部链接的函数都可以是内联函数。对于   具有外部链接的功能,具有以下限制   apply:如果使用内联函数说明符声明函数,   那么它也应该在同一个翻译单元中定义。如果   转换中函数的所有文件范围声明   单位包括没有extern的内联函数说明符   该翻译单元中的定义是内联定义。一个   内联定义不提供外部定义   功能,并不禁止另一个外部定义   翻译单位。内联定义提供了替代   外部定义,翻译人员可以用来实现任何内容   在同一个翻译单元中调用该函数。 是的   未指定对函数的调用是否使用内联   定义或外部定义。

因此,编译器可以自由使用myfunc的外部定义 - 如果不提​​供它,则不存在,因此链接器错误。为什么它更喜欢选择不存在的外部定义?因为您不允许使用-finline-functions或包含此标志的优化级别进行内联。

答案 1 :(得分:5)

这是gnu_inline打嗝。使用-std=gnu99 -fgnu89-inline

有关详细信息,请参阅Function Attributes(项gnu_inline)。

相关段落:

  

在C中,如果函数既不是extern也不是static,那么该函数被编译为独立函数,并且尽可能内联。

     

这是GCC传统上处理内联声明的函数的方式。由于ISO C99为内联指定了不同的语义,因此该函数属性作为转换度量提供,并且作为其自身的有用特性提供。此属性在GCC 4.1.3及更高版本中可用。如果定义了预处理器宏 GNUC_GNU_INLINE GNUC_STDC_INLINE ,则可以使用它。请参阅内联函数与宏一样快。

答案 2 :(得分:3)

您应该在定义之前声明'myfunc'。 例如,可以使用-std = gnu99选项编译此代码:

#include <stdio.h>

int myfunc(int);

inline int myfunc (int x) {
    return x+3;
}

int main () {

    printf("%d", myfunc(2));
    return 0;
}

<强>已更新

实际上,关于C标准inline关键字只是对C编译器的建议。但编译器可以选择不内联。因此,它可以以自己的方式。

在您的示例中,您可以使用上面显示的函数声明 - 或者您可以添加优化标志'-O3'(在linux gcc上测试)及以上 - 在这种情况下您的源代码将被编译没有额外声明。

<强>已更新

您可以在此处找到更深入的解释:https://blogs.oracle.com/dew/entry/c99_inline_function

答案 3 :(得分:1)

显然您需要指定您正在使用并且您想要采用内联函数

  
-fgnu89-inline
         

选项-fgnu89-inline告诉GCC在C99模式下使用传统的GNU语义作为“内联”函数。这个选项是     接受并被GCC版本4.1.3忽略但不包括在内     4.3。在GCC版本4.3及更高版本中,它改变了GCC在C99模式下的行为。使用此选项大致相当于添加     “gnu_inline”函数属性为所有内联函数。

         

选项-fno-gnu89-inline明确告诉GCC在C99或gnu99模式下使用C99语义为“inline”(即它     指定默认行为)。首先支持此选项     GCC 4.3。 C89或gnu89模式不支持此选项。

         

预处理器宏__GNUC_GNU_INLINE____GNUC_STDC_INLINE__可用于检查哪些语义在     对“内联”函数的影响。

  
     

来源:http://linux.die.net/man/1/gcc

所以要编译你的代码至少需要这个:

gcc source.c -std=gnu99 -fgnu89-inline