以下代码:
#include <stdio.h>
inline int myfunc (int x) {
return x+3;
}
int main () {
printf("%d", myfunc(2));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用-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
Run Code Online (Sandbox Code Playgroud)
-std=gnu99省略时编译没有问题.有谁知道链接器为什么会抱怨-std=gnu99使用?
在C99中,您需要为内联函数指定一个声明,如
int myfunc(int);
Run Code Online (Sandbox Code Playgroud)
或者允许编译器通过指定-finline-functions或实际内联函数-O3.
引用C99标准:
具有内部链接的任何函数都可以是内联函数.对于具有外部链接的函数,以下限制适用:如果使用内联函数说明符声明函数,则它也应在同一转换单元中定义.如果转换单元中函数的所有文件范围声明都包含不带extern的内联函数说明符,则该转换单元中的定义是内联定义.内联定义不提供函数的外部定义,也不禁止另一个转换单元中的外部定义.内联定义提供了外部定义的替代,翻译器可以使用该定义在同一翻译单元中实现对该功能的任何调用. 未指定对函数的调用是使用内联定义还是使用外部定义.
因此,编译器可以自由使用外部定义myfunc- 如果不提供它则不存在,因此链接器错误.为什么它更喜欢选择不存在的外部定义?因为您不允许通过不使用内联-finline-functions或包含此标志的优化级别.
这是gnu_inline打嗝.使用-std=gnu99 -fgnu89-inline.
有关更多信息,请参阅函数属性(项目gnu_inline).
相关段落:
在C中,如果函数既不是extern也不是static,那么函数被编译为独立函数,并且尽可能内联.
这就是GCC传统上处理内联声明的函数的方式.由于ISO C99为内联指定了不同的语义,因此该函数属性作为转换度量提供,并且作为其自身的有用特性提供.此属性在GCC 4.1.3及更高版本中可用.如果定义了预处理器宏GNUC_GNU_INLINE或GNUC_STDC_INLINE中的任何一个,则它可用.请参阅内联函数与宏一样快.