2011-03-21 13 views
6

虛擬函數是如何在位置無關的代碼中實現的?位置無關的代碼和虛擬表

我知道如果我的類具有虛函數,編譯器通常會爲其生成一個包含所有虛函數地址的vtable,並在我的類的每個對象中存儲一個指向vtable的指針。

現在,如果我的代碼是位置無關的,編譯器無法知道虛擬函數(或任何函數,地址)的地址。那它有什麼作用?

我想知道真正的編譯器是做什麼的(不是理論上可行的);我主要對linux 32位平臺感興趣,但其他平臺也很有趣。

+0

鏈接器知道,只要不跨越模塊邊界,修正偏移就不會有問題。找到一個實際做到這一點將是更難的問題。 – 2011-03-21 14:31:25

回答

7

有兩種選擇:

  1. 接受你的虛函數表不會是獨立的位置,並嘗試將其遠離代碼段移動,從而使需要動態連接的修正所有代碼人住彼此以減少不可共享頁面的數量。 gcc做這個
  2. 在vtable中使用相對跳轉。我沒有意識到有這樣做的實現,只有當vtable與方法實現有固定的偏移量時纔會起作用,並且這些實現在加載時不能被覆蓋(它們可以在典型的ELF系統上)。
-1

基本上,一個虛擬表無處不在實現爲一個函數指針表。