2013-11-25 15 views
1

C++代碼構造和c的析構函數組件++

#include <cstdio> 
#include <cstdlib> 

struct trivialStruct 
{   

trivialStruct(); 
~trivialStruct(); 

int *a; 
float *b; 
float *c; 

}; 

trivialStruct::trivialStruct() : a((int*)malloc(sizeof(int))), b((float*)malloc(sizeof(float))), c((float*)malloc(sizeof(float))) 
{ 
    *a = 100; 
    *b = 200; 
    *c = 300; 
} 

trivialStruct::~trivialStruct() 
{ 
    free(a); 
    free(b); 
    free(c); 

    a = nullptr; 
    b = nullptr; 
    c = nullptr; 
} 

int main() 
{ 
    trivialStruct A; 
    printf("%d, %f, %f", *A.a, *A.b, *A.c); 

    return 0; 
} 

組件

.section __TEXT,__text,regular,pure_instructions 
    .globl __ZN13trivialStructC1Ev 
    .align 4, 0x90 
__ZN13trivialStructC1Ev:    ## @_ZN13trivialStructC1Ev 
    .cfi_startproc 
## BB#0:        ## %entry 
    push RBP 
Ltmp3: 
    .cfi_def_cfa_offset 16 
Ltmp4: 
    .cfi_offset rbp, -16 
    mov RBP, RSP 
Ltmp5: 
    .cfi_def_cfa_register rbp 
    push R15 
    push R14 
    push RBX 
    push RAX 
Ltmp6: 
    .cfi_offset rbx, -40 
Ltmp7: 
    .cfi_offset r14, -32 
Ltmp8: 
    .cfi_offset r15, -24 
    mov RBX, RDI 
    mov EDI, 4 
    call _malloc 
    mov R14, RAX 
    mov QWORD PTR [RBX], R14 
    mov EDI, 4 
    call _malloc 
    mov R15, RAX 
    mov QWORD PTR [RBX + 8], R15 
    mov EDI, 4 
    call _malloc 
    mov QWORD PTR [RBX + 16], RAX 
    mov DWORD PTR [R14], 100 
    mov DWORD PTR [R15], 1128792064 
    mov DWORD PTR [RAX], 1133903872 
    add RSP, 8 
    pop RBX 
    pop R14 
    pop R15 
    pop RBP 
    ret 
    .cfi_endproc 

    .globl __ZN13trivialStructC2Ev 
    .align 4, 0x90 
__ZN13trivialStructC2Ev:    ## @_ZN13trivialStructC2Ev 
    .cfi_startproc 
## BB#0:        ## %entry 
    push RBP 
Ltmp12: 
    .cfi_def_cfa_offset 16 
Ltmp13: 
    .cfi_offset rbp, -16 
    mov RBP, RSP 
Ltmp14: 
    .cfi_def_cfa_register rbp 
    push R15 
    push R14 
    push RBX 
    push RAX 
Ltmp15: 
    .cfi_offset rbx, -40 
Ltmp16: 
    .cfi_offset r14, -32 
Ltmp17: 
    .cfi_offset r15, -24 
    mov RBX, RDI 
    mov EDI, 4 
    call _malloc 
    mov R14, RAX 
    mov QWORD PTR [RBX], R14 
    mov EDI, 4 
    call _malloc 
    mov R15, RAX 
    mov QWORD PTR [RBX + 8], R15 
    mov EDI, 4 
    call _malloc 
    mov QWORD PTR [RBX + 16], RAX 
    mov DWORD PTR [R14], 100 
    mov DWORD PTR [R15], 1128792064 
    mov DWORD PTR [RAX], 1133903872 
    add RSP, 8 
    pop RBX 
    pop R14 
    pop R15 
    pop RBP 
    ret 
    .cfi_endproc 

    .globl __ZN13trivialStructD1Ev 
    .align 4, 0x90 
__ZN13trivialStructD1Ev:    ## @_ZN13trivialStructD1Ev 
    .cfi_startproc 
## BB#0:        ## %entry 
    push RBP 
Ltmp21: 
    .cfi_def_cfa_offset 16 
Ltmp22: 
    .cfi_offset rbp, -16 
    mov RBP, RSP 
Ltmp23: 
    .cfi_def_cfa_register rbp 
    push RBX 
    push RAX 
Ltmp24: 
    .cfi_offset rbx, -24 
    mov RBX, RDI 
    mov RDI, QWORD PTR [RBX] 
    call _free 
    mov RDI, QWORD PTR [RBX + 8] 
    call _free 
    mov RDI, QWORD PTR [RBX + 16] 
    call _free 
    mov QWORD PTR [RBX + 16], 0 
    mov QWORD PTR [RBX + 8], 0 
    mov QWORD PTR [RBX], 0 
    add RSP, 8 
    pop RBX 
    pop RBP 
    ret 
    .cfi_endproc 

    .globl __ZN13trivialStructD2Ev 
    .align 4, 0x90 
__ZN13trivialStructD2Ev:    ## @_ZN13trivialStructD2Ev 
    .cfi_startproc 
## BB#0:        ## %entry 
    push RBP 
Ltmp28: 
    .cfi_def_cfa_offset 16 
Ltmp29: 
    .cfi_offset rbp, -16 
    mov RBP, RSP 
Ltmp30: 
    .cfi_def_cfa_register rbp 
    push RBX 
    push RAX 
Ltmp31: 
    .cfi_offset rbx, -24 
    mov RBX, RDI 
    mov RDI, QWORD PTR [RBX] 
    call _free 
    mov RDI, QWORD PTR [RBX + 8] 
    call _free 
    mov RDI, QWORD PTR [RBX + 16] 
    call _free 
    mov QWORD PTR [RBX + 16], 0 
    mov QWORD PTR [RBX + 8], 0 
    mov QWORD PTR [RBX], 0 
    add RSP, 8 
    pop RBX 
    pop RBP 
    ret 
    .cfi_endproc 

    .section __TEXT,__literal8,8byte_literals 
    .align 3 
LCPI4_0: 
    .quad 4641240890982006784  ## double 200 
LCPI4_1: 
    .quad 4643985272004935680  ## double 300 
    .section __TEXT,__text,regular,pure_instructions 
    .globl _main 
    .align 4, 0x90 
_main:         ## @main 
    .cfi_startproc 
## BB#0:        ## %entry 
    push RBP 
Ltmp34: 
    .cfi_def_cfa_offset 16 
Ltmp35: 
    .cfi_offset rbp, -16 
    mov RBP, RSP 
Ltmp36: 
    .cfi_def_cfa_register rbp 
    lea RDI, QWORD PTR [RIP + L_.str] 
    movsd XMM0, QWORD PTR [RIP + LCPI4_0] 
    movsd XMM1, QWORD PTR [RIP + LCPI4_1] 
    mov ESI, 100 
    mov AL, 2 
    call _printf 
    xor EAX, EAX 
    pop RBP 
    ret 
    .cfi_endproc 

    .section __TEXT,__cstring,cstring_literals 
L_.str:         ## @.str 
    .asciz "%d, %f, %f" 


.subsections_via_symbols 

命令 鐺++ -S -O2 -std = C++ 11 -mllvm --x86-ASM-語法=英特爾-fno-例外的main.cpp

正如你所看到的,有碼的兩個部分是相同的(構造函數和析構函數)

  1. __ZN13trivialStructC1Ev:## @ _ZN13trivialStructC1Ev
  2. __ZN13trivialStructC2Ev:## @ _ZN13trivialStructC2Ev
  3. __ZN13trivialStructD1Ev:## @ _ZN13trivialStructD1Ev
  4. __ZN13trivialStructD2Ev:## @ _ZN13trivialStructD2Ev

我不知道爲什麼編譯器生成兩部分代碼,但不只是一個? 我並不熟悉程序集,但看起來像這樣只是使代碼變得更胖(也許更慢)。

+1

嘗試優化代碼大小(將'-Os'傳遞給g ++)。此外,較少的代碼並不總是更好 - 分支可能非常昂貴。 –

+1

請注意,代碼不會*慢*。如果不使用構造函數,鏈接器可能會刪除符號(請閱讀鏈接器的文檔),即使它們未被刪除,它們也會佔用一些內存空間,但不會被評估(即不會導致其他代碼被從緩存中刪除)。 –

回答

3

這是您的平臺的ABI的一部分,並且逃脫了標準。構造函數和析構函數都可以在二進制文件中生成多個符號。例如,安騰C++ ABI將產生最多3構造/解構:

  • 完整對象構造
  • 基礎對象構造
  • 完整對象分配構造
  • 刪除析
  • 完整的對象析構函數
  • 基礎對象析構函數

不同的符號承擔了不同的責任,因爲實施可能需要根據對象被創建/銷燬的方式做不同的事情。在您的具體情況中,代碼非常簡單,所有構造函數都可以生成完全相同的代碼,但它們需要在那裏才能符合ABI,並且ABI讓它們可以啓用更復雜的用例。

例如,一個完整的對象構造函數將初始化虛擬基礎,而基礎對象構造函數將跳過這部分構造。如果存在多個/虛擬繼承和虛擬函數,則完整對象中的vptr可能必須跳過不同的中間表集,具體取決於該子對象如何實例化。

如果您需要的解釋不是ABI要求,您應該查看您的特定ABI的文檔。你也可以看看在C++對象模型裏面,即使是古老的,也包含了對要解決的問題和所提供的一些解決方案的很好描述。