我有一個類定義在一個h文件中,並在一個cpp中實現,這是一個lib的一部分(我們將其稱爲libdef)。Linux C++編譯器(和鏈接器)如何決定將typeinfo放在哪裏?
我有兩個其他庫有cpp文件,包括這個h文件。其中一個對這個類執行dynamic_cast()(我們稱它爲libdyn),另一個爲這個類做了新的操作(我們稱它爲libnew)。
看來,在這些庫中的一個有所屬類別的類型,但不是在其他:
[email protected]> ld --cref libdef.so | grep -E "typeinfo for MyClass"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdef.so
[email protected]> ld --cref libnew.so | grep -E "typeinfo for MyClass"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdef.so
[email protected]> ld --cref libdyn.so | grep -E "typeinfo for MyClass"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdyn.so
正如你可以看到兩個libdef和libnew使用來自libdef的所屬類別,但libdyn使用它自己所屬類別。這是爲什麼?編譯器/鏈接器如何決定是將typeinfo放入一個庫還是從另一個庫引用?
我應該注意libnew和libdyn都是用-llibdef構建的。
[email protected]> icpc -V
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 12.0.0.084 Build 20101006
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.
[email protected]> ld -V
GNU ld version 2.17.50.0.6-14.el5 20061020
Supported emulations:
elf_x86_64
elf_i386
i386linux
經過一些檢查後,它取決於lib的cpp文件是否「查看」虛擬方法定義。
此代碼將不會導致所屬類別庫中的元件是:
class SomeClass { public: SomeClass(); virtual void func(); };
此代碼將在庫中產生一個所屬類別符號:
class SomeClass { public: SomeClass() {} virtual void func() {} };
當存在時,所屬類別符號將有模糊的聯繫。
您似乎認爲每種類型只有一個typeinfo對象...標準不能保證這一點,它只能保證如果有多個,它們會比較相等。 – 2011-05-23 13:27:30
@Ben問題是,如果有多個,它們在Linux中並不相等(因爲使用了地址比較)。如果您只是在gcc告訴您使用庫時纔會發生這種情況,但我們仍然遇到問題,並且正在嘗試爲我們的產品尋找一些解決方法。 – selalerer 2011-05-23 17:22:50
通過「比較等於」,我不是說地址比較。我的意思是'operator =',它是爲'typeinfo'類型的對象定義的。這是標準保證將用於比較typeinfo實例的唯一機制。 – 2011-05-23 20:32:03