2つの個別のCPPファイルで定義されたインライン関数は、リンク中に重複したシンボルを作成できますか?

StackOverflow https://stackoverflow.com/questions/19843380

質問

私は多くのリソースをオンラインでハーピングする方法を見つけます inline (そしてさらに __attribute__((always_inline)) また __forceinline)コンパイラ(GCCまたはVisualC ++など)に関数をインラインにしないでください。しかし、いつ正確にインラインが強制されないのでしょうか?おもちゃの例はありますか?

おそらく必ずしも同じ質問ではありません。 inline 2つの異なるCPPファイルに含まれています。リンケージ中に問題が発生しますか?つまり、重複したシンボルを生成しますか?

これは、コンパイラを破壊し、重複したシンボルを生成しようとするための具体的なサンドボックスです。

myinline.h:

inline int myinline()
{
  // code that cannot be inlined...
  ...
}

aux.cpp:

#include "myinline.h"
int aux()
{
  return my_inline();
}

main.cpp:

#include "myinline.h"
int aux();
int main()
{
  return aux() + my_inline();
}

次に、GCCの場合、(最小限の)コードがあります myinline これにより、次のようにコンパイルおよびリンクするときに重複した記号が発生します。

g++ -o aux.o -c aux.cpp
g++ -o main.o -c main.cpp
g++ -o example aux.o main.o

?

役に立ちましたか?

解決

「インランス」と「重複したシンボル」は異なるものです。 inline キーワードでは、複数の定義を明示的に許可します(つまり、1つの定義ルールから免除されます)ため、プラットフォーム(コンパイラとリンカー)は、それを処理し、強化する方法を知っている必要があります。

(これは、ヘッダーで定義されているクラスメンバー関数に対して常に発生します。)

あなたがただ欲しいなら コード生成 起こるために、あなたはどこかに関数のアドレスを保存することができます:

auto fp = my_inline;

そうすれば、コンパイラがアドレスを与えることができるように、関数の定義を生成する必要があります。ただし、すべての翻訳ユニットでこれを行う場合でも、リンカーエラーは表示されません。これはリンク時に重複するためです。すべての定義が同一であるという要件により、これが明確に定義されていることを確認します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top