簡體   English   中英

使用共享庫和不匹配的編譯器

[英]Using shared libraries and mismatched compilers

使用使用不同編譯器版本編譯的共享庫比您的程序引入問題的機會有多大?

如果您的程序使用的語言標准與它們不同怎么辦?

即,如果我在使用 gcc-6,c++14 編譯我的代碼時鏈接使用 gcc-4.8,c++11 編譯的 boost 庫,這會不會是一個問題?

簡短的回答,接近 100% 你會遇到一些問題,除非圖書館的設計考慮到這一點。 Boost 的設計根本沒有考慮到這一點,它不會起作用。

長答案,它可能在某些非常特定的情況下起作用(盡管不是為了提升)。 有兩個主要的事情可以發揮作用:

  • ABI 兼容性
  • 子庫兼容性/內聯代碼

ABI 是簡單的部分。 例如,如果編譯器 A 與編譯器 B 的名稱不同,它甚至不會鏈接。 或者,如果他們有不同的調用約定(例如,參數如何通過寄存器/堆棧等傳遞),那么它可能會鏈接,但它根本無法工作/以非常明顯的方式崩潰。 此外,同一平台上的大多數編譯器具有相同的調用約定(或可以進行適當配置),因此這應該不是一個大問題。

子庫兼容性和內聯代碼更棘手。 例如,假設您有一個傳遞已分配對象的庫,而解除分配是客戶端的工作。 如果庫的分配器的工作方式與客戶端中的分配器不同,那么這將導致問題(例如,庫使用編譯器 A 的new ,而主程序使用編譯器 B 的delete )。

或者頭文件中可能有代碼(例如內聯方法)。 兩個編譯器可能會以不同的方式編譯它們,這會導致問題。

或者庫可能會返回一個std::vector 編譯器 A 的vector的實現可能與編譯器 B 的vector ,因此這也不起作用。

或者可能有一個結構或類被傳遞。 兩個編譯器可能不會以相同的方式打包/填充它們,因此它們在內存中的布局方式不會相同,並且事情會崩潰。

因此,如果庫的設計考慮到了這一點,那么它可能會起作用。 一般來說,這意味着:

  • 所有調用都必須是extern C以避免名稱混淆。
  • 不傳遞任何外部定義的結構(例如 STL)
  • 除非兩個編譯器中的打包/填充相同,否則即使structs也可能導致問題
  • 庫分配的所有內容也必須由庫釋放
  • 不拋出異常(這是extern C隱含的)
  • 可能還有一些我現在忘記了

如果 ABI(和 API)相同,它將正常工作,根據 gcc.gnu.org 的ABI 政策和指南,“給定使用給定編譯器 ABI 和庫 API 編譯的應用程序,它將與標准 C++ 一起正常工作使用相同約束創建的庫。”

使用不同 ABI 編譯的共享庫可以工作,但在某些情況下需要注意,因為它們可能導致難以檢測的重大錯誤。

gcc-4.8 和 gcc-6 具有不同的 ABI(應用程序二進制接口),因此在非常特定的情況下可能會輸出不同的編譯代碼,並導致應用程序中斷。

但是,“ GNU C++ 編譯器 g++ 有一個編譯器命令行選項可以在各種不同的 C++ ABI 之間切換。 ”(根據 ABI 政策和指南。)

您可以從gcc.gnu.org閱讀有關特定 ABI 問題的更多詳細信息:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM