2009-09-29 88 views
6

如果我在C++中有多個鏈接的C++靜態鏈接庫,如果它們使用不同的啓用/禁用運行時間值進行編譯,是否可以共享(傳入和傳出函數)類對象類型信息(RTTI)?在C++中混合使用RTTI標誌

- 編輯: 感謝您的回覆,我擔心的具體事情是 1.是否啓用RTTI更改靜態(非多態類型)的sizeof行爲?

and 2.如果我在支持RTTI的庫中創建類並將其傳遞給另一個不支持RTTI的庫,那麼虛擬方法是否正常工作。 (反之亦然)

and lastly 3.如果我在支持RTTI的庫中創建類,我希望能夠使用dynamic_cast,如果我將該對象傳遞給啓用了非RTTI的庫,可以我仍然使用的對象。 ......我不會假設,反正這似乎是一個壞主意......我只是好奇。

回答

6

RTTI信息如何存儲是一個實現細節,因此不能跨不同編譯器移植。

而且大多數編譯器甚至不保證標誌不同的編譯對象將使用相同的ABI因爲有方法。這在發佈和調試庫中最顯着,但其他標誌也可能會導致差異。

不僅可以在ABI爲函數/方法改變,但標誌可以影響結構元件之間所使用的編譯器。因此,當具有不同的標誌編譯沒有虛擬方法甚至對象可以是不相容的填充。

使用大多數IDS時,您可以看到效果。調試/發佈二進制文件被內置到獨立目錄中,並且僅針對相同種類的二進制文件進行鏈接(由於標誌差異可能導致不兼容,因此任何用戶定義的版本都將內置到單獨的唯一目錄中)。如果您更改構建中的某些標誌,那麼整個項目通常會被迫重新構建。

+0

這裏沒有其他人想到的優秀點,特別是有關填充的問題取決於編譯器設置。 – Elemental 2009-09-29 16:00:33

+0

@Loki Astari:是否暗示如果我使用.so或.dll中的對象(禁用RTTI進行編譯),我將無法使用dynamic_cast,也不能爲該對象使用typeid。或者更糟糕的是,ABI不正確,所以程序不兼容(可能是崩潰等)。 – 2012-09-12 00:07:55

+0

@ Shao-ChuanWang:潛在的。這一切都取決於你的編譯器。爲了安全起見,所有對象必須使用完全相同的標誌進行編譯。 – 2012-09-12 00:30:57

1

這取決於你在說什麼特定的C++編譯器 - 我近期沒有真正的跨平臺C++經驗(近年來我的C++工作幾乎完全用Linux上的C++),但幾年以前我敢打賭,gcc會允許你逃避相當多的這樣的混混,Visual C++「沒有辦法」,其他編譯器有點在中間...!)

0

只要類共享不是多態(即,他們不包含虛函數),這不會是一個問題。但是,您將無法使用dynamic_cast,禁用RTTI的typeid和例外。

+0

不同的標誌可能會導致結構中的填充不同,從而導致對象跨庫不兼容。 – 2009-09-29 10:48:20