web-dev-qa-db-ja.com

.cファイルのC99インライン関数

次のように、関数を.c(ヘッダー宣言なし)で定義しました。

inline int func(int i) {
 return i+1;
}

次に、以下の同じファイルで使用します:

...
i = func(i);

そして、リンク中に「 'func'への未定義の参照」を取得しました。どうして?

36
user14416

C99インラインセマンティクスはしばしば誤解されます。 inline指定子には2つの目的があります。

最初に、static inlineおよびextern inline宣言の場合のコンパイラーのヒントとして。指定子を削除しても、セマンティクスは変更されません。

第二に、未加工のinline(つまりstaticまたはexternなし)の場合、別の場所に存在する必要がある外部定義の代替としてインライン定義を提供します。翻訳単位。外部のものを提供しないことは未定義の動作であり、通常はリンクの失敗として現れます。

これは、関数を共有ライブラリに入れたいが、関数本体を最適化(インライン化や特殊化など)できるようにする場合に特に便利です。十分にスマートなコンパイラを想定すると、これにより、プリプロセッサフ​​ープをジャンプすることなく、C++テンプレートの多くの利点を回復できます。

定義自体がextern inlineではなくinlineであっても、Jensの答えで説明されているように、別のファイルスコープの非インライン外部宣言が最初のケースをトリガーするため、ここで説明するよりも少し厄介です。これは仕様によるものであるため、ヘッダーファイルに単一のインライン定義を含めることができます。これは、外部宣言に1行追加することで、外部定義を提供するソースファイルに含めることができます。

32
Christoph

これは、GCCがインライン関数を処理する方法が原因です。 GCCは最適化の一部としてインライン置換を実行します

このエラーを削除するには、インラインの前にstaticを使用します。 staticキーワードは、静的キーワードを使用するコンパイラーに強制的にコンパイラーに、プログラムを正常にコンパイルさせるこのインライン関数を強制します。

static inline int func(int i) {
 return i+1;
}
...
i = func(i);
0
Niloy Rashid