2016-11-02 108 views
8

我想明白爲什麼內聯函數的libC++可見性宏使用__forceinline__attribute__((__always_inline__))作爲它與內聯函數關聯的屬性的一部分。爲什麼libcxx會將__forceinline或GCC等效於其已經隱藏的內聯函數?

有關背景看:

如果這些內聯函數將被標記爲__visibility__("hidden")反正,爲什麼需要另外強制編譯器內聯它們?

我已經想了一下,我有幾個假說,但沒有一個似乎完全滿意的對我說:

  • 這是爲了確保符號不小心成爲ABI的一部分。如果在構建庫時編譯器選擇不內聯函數,它可能會成爲外部符號,因此也是ABI的一部分。但hidden屬性不會足夠嗎?同樣,在建立圖書館時,是否有必要強制內聯函數?消費者不應該在意。
  • 它是爲了確保函數從來沒有定義,以避免ODR問題,編譯器選擇不內聯庫中的函數,並選擇不內聯在由客戶端生成的代碼中的函數圖書館,導致兩個不同的定義。但是,這不是預期(並接受)使用visibility("hidden")的結果嗎?
  • 這是作爲標準庫的實現而設計libC++的特定事情。

我問這是因爲我正在構建一個C++庫,我希望有一天能夠標準化ABI,並且我使用libC++作爲指導。到目前爲止,它運行良好,但這個問題已經引起了一些頭部搔抓。

特別是,我們有用戶抱怨MSVC拒絕兌現__forceinline屬性的報告,導致警告。我們提出的解決方案是,在構建庫時,我們的模擬擴展到INLINE_VISIBILITY只包括__forceinline(或GCC等效),假設上面的第一個解釋。

但是,由於我們並不完全相信我們理解強制內聯函數的原因是首先是__forceinline__attribute__((__always_inline__)),我們對採用此解決方案有些猶豫。

任何人都可以提供一個明確的答案,爲什麼libC++覺得需要強制內聯其內聯函數,即使它們已經被裝飾爲隱藏可見性?

回答

4

我可能處於最好的位置來解決這個問題,因爲我是做這件事的人之一。你可能不喜歡答案。 :-)

當我創建libC++時,我唯一的目標是macOS(OS X)。這是libC++開源之前的方式。而且我強制內聯的主要動機是控制dylib的ABI,這會隨着操作系統版本的推出而推出。一個強制內聯函數永遠不會出現在一個dylib中,因此我可以指望它獨佔一個頭部(與OS版本有不同的交付系統)。

我從來沒有考慮過「隱藏」這個附加屬性作爲這個決定的一部分,因爲這對我來說只是一個不必要的複雜因素。我希望這個函數能夠生存在一個頭文件中,並且永遠不會被放入dylib中,那就是這樣。所以你的第一個子彈是我相信是正確的。

我很高興libC++已經超出了原來的範圍,我希望你能夠繼續努力。我很樂意提供任何額外的信息,我可能會幫助你實現你的目標。

+0

我喜歡這個答案很好,謝謝你花時間回覆。聽起來好像我們可以繼續前進,並重新評估我們的__forceinline貨運結果是否是不必要的,應該刪除。這聽起來很可能。另外,如果您有興趣瞭解我們正在採取的方法或提供任何反饋,相關圖書館是libmongocxx:https://github.com/mongodb/mongo-cxx-driver/tree/master – acm

相關問題