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 では、関数が extern でも static でもない場合、関数はスタンドアロン関数としてコンパイルされ、可能な場合はインライン化されます。

これは、インラインで宣言された関数を GCC が伝統的に処理する方法でした。ISO C99 はインラインに対して異なるセマンティクスを指定しているため、この関数属性は移行手段として、またそれ自体が有用な機能として提供されています。この属性は、GCC 4.1.3 以降で使用できます。プリプロセッサ マクロGNUC_GNU_INLINEまたはGNUC_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標準のインラインキーワードに関しては、Cコンパイラへの提案にすぎません。ただし、コンパイラはインライン化しないことを選択できます。したがって、独自の方法で実行できます。

あなたの例では、上で示したように関数宣言を使用できます-または最適化フラグ'-O3'(linux gccでテスト済み)以上を追加できます-この場合、ソースコードは余分な宣言なしでコンパイルされます。

更新しました

ここでより深い説明を見つけることができます:https ://blogs.oracle.com/dew/entry/c99_inline_function

于 2012-10-05T13:30:35.410 に答える
1

どうやら、使用していることを指定する必要があり、インライン関数を採用したい

-fgnu89-inline

オプション -fgnu89-inline は、C99 モードの場合、「インライン」関数に従来の GNU セマンティクスを使用するよう GCC に指示します。このオプションは、GCC バージョン 4.1.3 から 4.3 までは受け入れられ、無視されます。GCC バージョン 4.3 以降では、C99 モードでの GCC の動作が変更されます。このオプションを使用することは、「gnu_inline」関数属性をすべてのインライン関数に追加することとほぼ同じです。

オプション -fno-gnu89-inline は、C99 または gnu99 モードの場合に「インライン」に C99 セマンティクスを使用するよう GCC に明示的に指示します (つまり、デフォルトの動作を指定します)。このオプションは、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 に答える