以下代码:
#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
链接器为什么会抱怨?
答案 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__
可用于检查哪些语义在 对“内联”函数的影响。
所以要编译你的代码至少需要这个:
gcc source.c -std=gnu99 -fgnu89-inline