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

C 使用-std=gnu99和内联函数时出现编译错误,c,gcc,C,Gcc,以下代码: #include <stdio.h> inline int myfunc (int x) { return x+3; } int main () { printf("%d", myfunc(2)); return 0; } 当省略-std=gnu99时,编译不会出现问题。有人知道如果使用了-std=gnu99,链接器为什么会抱怨吗?您应该在定义“myfunc”之前声明它。 例如,可以使用-std=gnu99选项编译此代码: #include

以下代码:

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

int main () {

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

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

您应该在定义“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;
}
#包括
int-myfunc(int);
内联int myfunc(int x){
返回x+3;
}
int main(){
printf(“%d”,myfunc(2));
返回0;
}
已更新

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

在您的示例中,您可以使用我上面所示的函数声明——或者您可以添加优化标志“-O3”(在linux gcc上测试)和更高版本——在这种情况下,您的源代码将在不进行额外声明的情况下编译

已更新


在这里您可以找到更深入的解释:

这是
gnu内联
hiccup。使用
-std=gnu99-fgnu89内联

有关更多信息,请参见(项目
gnu\u inline

相关段落:

在C语言中,如果函数既不是外部函数也不是静态函数,那么函数将被编译为独立函数,并尽可能内联

这是GCC传统上处理内联声明函数的方式。由于ISO C99为内联指定了不同的语义,因此此函数属性本身就是一种转换度量和有用的特性。此属性在GCC 4.1.3及更高版本中可用。如果定义了预处理器宏GNUC_GNU_INLINEGNUC_STDC_INLINE,则此选项可用。请看,内联函数与宏一样快


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

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

选项-fno-gnu89-inline显式地告诉GCC在C99或gnu99模式下使用“inline”的C99语义(即 指定默认行为)。此选项最初在中得到支持 GCC 4.3。C89或gnu89模式下不支持此选项

预处理器宏
\uuuu GNUC\u GNU\u INLINE\uuu
\uuu GNUC\u STDC\u INLINE\uu
可用于检查所使用的语义 “内联”函数的效果

资料来源:

因此,要编译代码,您至少需要:

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

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

int myfunc(int);
或者允许编译器通过指定
-finline函数
-O3
来实际内联函数

引用C99标准:

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


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

很有趣。我用4.4.3进行了测试,它也给了我同样的错误。我在玩
gnu99
时也发现了这一点,但这是标准的C99行为:但是你如何解释没有声明和
内联的编译呢?有趣的。。。我之前在定义之前声明过函数,但是如果使用
inline int myfunc(int),则会出现相同的编译错误。为什么这里要省略内联?顺便说一句,我还通过将
myfunc
声明为
extern
获得了要编译的代码。这应该不是必需的。实际上这是C99内联故障。
gcc source.c -std=gnu99 -fgnu89-inline
int myfunc(int);