2011-12-05 7 views
1

参照文書情報: インラインメソッド隠し GCC_INLINES_ARE_PRIVATE_EXTERN =有効にするとYES 、インライン方式のアウトオブラインコピーが宣言されている '民間のextern' [GCC_INLINES_ARE_PRIVATE_EXTERN、-fvisibility-インライン-隠さXCode4の "Inline Methods Hidden"オプション。

んが。誰もがC++ライブラリをどのように受けるのか知っていますか?私のiPhoneプロジェクトはC++ライブラリをベースにしていますが、Googleのprotobufを使用しています。ライブラリインライン関数が "インラインメソッド隠し"オプションによってYESに設定されているという奇妙な問題が見つかりました。まあ、私はなぜか分からないのですか?内部の秘密は何ですか?

このトピックに興味のある方は、事前に感謝の意を表することができます。

答えて

2

秘密は1つの定義ルールです。インラインが隠れ​​ていると、イメージごとに複数(プライベート)のインラインコピーが作成される可能性があります。

理想的には、1つの定義ルールを使用して機能するようにすべてを構成して使用すると、プライベートエクスターナルを最適化として有効にすることができます。このアプローチは、標準のモデルに従うので、あなたはこのアプローチに賛成するでしょう。

ODRに迅速復習について:

// somewhere.hpp 
namespace MON { 
inline int cas(const int*,const int*,int*) { 
    return dah_dum(); 
}} 

// elsewhere.hpp 
namespace MON { 
inline int cas(const int*,const int*,int*) { 
    return dum_dah(); 
}} 

全体的または部分的にインラインではなく、int MON::cas(const int*,const int*,int*)への関数呼び出しは関係なく定義のいずれかの定義の使用をもたらすことができる任意int MON::cas(const int*,const int*,int*)基準に見えたがTU。厳密に1つの定義はリンカーによって保持され、すべての定義はすべて等しいものとみなされます。これは、参照され可視になるすべての定義が、各翻訳のコピーを生成する場合、バイナリサイズが爆発的になるため重要です。

ODRのルールを使用するときに「うまくいく」とすれば、オブジェクトファイルには複数のシンボルの定義があり、コンパイラの設定によって異なる定義を参照することになります。 staticでも匿名の名前空間でもないインラインを宣言した場合、その定義はすべてのソースファイルで同じにする必要があります。

これをC TUと混在させている場合は、リンクのルールが異なり、問題がさらに複雑になります。

+0

ご返信ありがとうございます。 "インラインメソッド隠し"オプションがYESに設定されていると、ライブラリインライン関数がトリガされないという奇妙な問題があります。なぜですか?多分、さらなるトレースが必要です。 – jianhua