2011-12-05 45 views
1

見文件信息: 聯方法隱藏 GCC_INLINES_ARE_PRIVATE_EXTERN = YES 啓用時,外的線聯方法副本聲明「私有外部」 [GCC_INLINES_ARE_PRIVATE_EXTERN,-fvisibility - 內聯隱藏「inline Methods Hidden」選項。

不會。任何人都知道它將如何影響C++庫?我的iPhone項目基於C++庫,使用谷歌protobuf,我發現一些奇怪的問題,庫內聯函數不會被「內聯方法隱藏」選項設置爲YES觸發,實際上它是系統默認值,設置爲NO好吧,我不知道爲什麼?裏面的祕密是什麼?

任何人誰對這個話題感興趣,請分享和討論,在此先感謝。

回答

2

祕密是一個定義規則。如果內聯是隱藏的,那麼您最終可能會有多個(私人)內聯副本。理想情況下,您可以配置和使用所有東西,使其能夠使用一個定義規則運行,然後您可以啓用私有extern作爲優化(這在各方面都可能不太好,尤其是二進制大小)。你會喜歡這種方法,因爲它遵循標準的模型。

有關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*)可能會導致在使用中任一定義的無論哪個定義是對可見恩。鏈接器保留了一個定義,並假定所有定義都相同。這很重要,因爲如果每個引用和可見的定義都會爲每個翻譯產生一個副本,那麼您的二進制大小將會爆炸。

如果在使用ODR規則時「有效」,那麼很可能您的對象文件中有給定符號的多個定義,並且最終由於編譯器設置而引用了不同的定義。如果你聲明瞭一個非靜態的inline或匿名的名字空間,那麼所有源文件的定義應該是相同的。

如果你將它與C TU混合,那麼......它有不同的連接規則,這隻會​​使事情進一步複雜化。

+0

謝謝你的回覆。 因爲我發現一些奇怪的問題,庫內聯函數不會被「內聯方法隱藏」選項設置爲YES觸發,爲什麼?也許需要進一步追蹤。 – jianhua