2009-11-05 50 views
2

我在想,編譯A類的一個編譯器不允許多重繼承,並且編譯一個支持它的類B(而B類是從A類派生的),會產生什麼後果。C++分類編譯器(vtables)?

我真的不明白鏈接過程...可以一起使用兩者嗎?在這種情況下使用不同的編譯器有什麼不利之處?使用B類的代碼能夠正常工作嗎?

謝謝。

+0

它可以概括爲:每個編譯器製造商都可以定義自己的ABI。由於ABI的不同使得一個編譯器的代碼不能被另一個編譯器使用,所以這個過程不可用。事實上,使用相同編譯器和不同標誌編譯的代碼會導致相同的問題(調試和發佈二進制文件與某些編譯器不兼容)。所以從技術上講,所有編譯單元都應該使用相同的標誌編譯相同的編譯器(否則你會遇到麻煩)。 – 2009-11-05 17:40:11

回答

10

作爲一般規則,不要有史以來用不同的編譯器編譯C++程序的一部分。

不同的編譯器可能會使用不同的編譯模式來處理符號重組階段,因此很難單獨編譯的內容之間的鏈接工作。

看到有關重整name_mangling

+0

另外,vtable實現,異常處理等(整個C++ ABI)可能會有所不同。 – sellibitze 2009-11-05 13:36:19

+0

感謝您的提醒。我絕不會這樣做。 – ash 2009-11-05 13:43:13

+0

如果您使用共享對象/ DLL,則可以這樣做。然後有一個通用的鏈接約定,以便不同的編譯器可以一起工作。如果你在外部供應商的應用程序中使用DLL,你不知道他們使用了什麼編譯器。 您將不得不將應用程序分解爲「組件」共享對象/ DLL。 – 2009-11-05 13:59:49

3

對象佈局(虛表指針的位置,虛函數表格式,子對象的位置,等)的文檔不保證是編譯器之間相同。

2

這不僅僅是不能相互交談的課程。在頭文件中聲明但僅由其中一個編譯器編譯的裸函數由於名稱變形而對其他編譯器不可見。

另外,由編譯器編譯的不編譯main()的任何靜態類/成員將不會正確初始化,因爲編譯器的運行時不會被執行。即使像64位長算術(在32位平臺上),由於衝突的運行時庫可能無法正確鏈接。

2

作爲附錄上述Arkaitz的職位,你可能會發現其他問題,可以停止碼從不同的編譯器內置的編譯單元一起工作:

  1. 數據大小的問題(例如,一個編譯器將使用32個整數,該其他64位)
  2. 數據對準問題
  3. 問題與堆內存

基本上任何地方的C++/C標準不是非常特定的事爲編譯器之間的差異留有餘地,因此可以混合使用它們的問題範圍