14

以下代码:

#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

4 回答 4

8

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

int myfunc(int);

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

引用 C99 标准:

任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,适用以下限制: 如果函数使用内联函数说明符声明,则它也应在同一翻译单元中定义。如果翻译单元中函数的所有文件范围声明都包含不带 extern 的内联函数说明符,则该翻译单元中的定义是内联定义。内联定义不为函数提供外部定义,也不禁止在另一个翻译单元中进行外部定义。内联定义提供了外部定义的替代方案,翻译器可以使用它来实现对同一翻译单元中函数的任何调用。 未指定对函数的调用是使用内联定义还是外部定义。

所以编译器可以自由地使用myfunc- 如果你不提供它就不存在的外部定义,因此链接器错误。为什么它更喜欢选择一个不存在的外部定义?-finline-functions因为您通过不使用或包含此标志的优化级别来禁止内联。

于 2012-10-05T15:11:52.880 回答
5

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

有关详细信息,请参阅函数属性(项gnu_inline)。

相关段落:

在 C 中,如果函数既不是外部函数也不是静态函数,则该函数被编译为独立函数,并在可能的情况下被内联。

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

于 2012-10-05T13:40:41.030 回答
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

于 2012-10-05T13:30:35.410 回答
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 语义来表示“内联”(即,它指定默认行为)。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
于 2012-10-05T13:41:53.557 回答