2014-09-24 95 views
3

我寫了一個簡單的C++程序與定義的類象下面這樣:(試驗是在x86 32位Linux的使用g ++ 4.6.3)爲什麼在g ++生成的彙編代碼中定義這樣的構造函數/析構函數?

#include <iostream> 

using namespace std; 

class Computer 
{ 
public: 
    Computer(); 
    ~Computer(); 
}; 

Computer::Computer() 
{ 
} 

Computer::~Computer() 
{ 
} 

int main() 
{ 
    Computer compute; 
    return 0; 
} 

當我使用g++產生ctorsdtors,我得到這些定義在.ctors的末尾。

.globl _ZN8ComputerC1Ev 
    .set _ZN8ComputerC1Ev,_ZN8ComputerC2Ev 
    .globl _ZN8ComputerD1Ev 
    .set _ZN8ComputerD1Ev,_ZN8ComputerD2Ev 

挖掘到生成的彙編代碼後,我想通了,_ZN8ComputerC1Ev應該類Computer被構造時所使用的函數名,而_ZN8ComputerC2Ev是類Computer的構造的名稱。同樣的事情發生在Computer的析構函數聲明和調用中。

看來,建立了一個鏈接構造函數及其實現。

所以我的問題是:

  1. 實際上是什麼這個構造函數/析構函數的信息?

  2. 我在哪裏可以找到它們的ELF格式?

我甩相關.ctors.init_array部分,但我就是無法找到_ZN8ComputerC1Ev_ZN8ComputerC2Ev之間形成的關係的元數據...

回答

2

這裏沒有桌子。 .globl.set是所謂的彙編指令僞操作。它們向彙編器發出信號,但不一定會產生實際的代碼或數據。從the docs

.global符號.globl符號

.global使得符號ld可見。如果您在 部分程序中定義了符號,則其值會與其他鏈接的部分程序 一起使用。否則,符號從鏈接到同一個 程序的另一個文件中獲取同名 符號的屬性。

.set符號,表達

設置符號表達的值。這改變了符號的值和 類型以符合表達式

因此,您引用的片段只是確保構造函數在其他編譯單元引用的情況下可用於鏈接。通常在最終ELF中看到的唯一影響是符號表中的這些符號的存在(如果它沒有被剝離)。

現在,您可能會好奇爲什麼您有兩個不同的構造函數名稱(例如_ZN8ComputerC1Ev_ZN8ComputerC2Ev)。答案有點複雜,所以我會向您推薦另一個SO問題,詳細解決它:

Dual emission of constructor symbols

相關問題