新的POD的c ++对象(普通旧数据类型)

时间:2013-11-20 05:03:43

标签: c++

对new和malloc做一些测试,我期待新的 需要比malloc更多的汇编代码,但它不是

clang ++ -S -mllvm --x86-asm-syntax = intel main.cpp

int main()
{
    char *a = new char[1024];
    delete []a;

    return 0;
}

的malloc

#include <cstdlib> // pulls in declaration of malloc, free

int main()
{
    char *a = (char*)malloc(1024);

    free(a);

    return 0;
}
好吧,char是一个POD,我想我不需要处理构造函数和析构函数的代价,但是新的确需要处理异常(即使我不添加-fno-exceptions,结果是相同的),组装怎么可能相同?

    .section    __TEXT,__text,regular,pure_instructions
    .globl  _main
    .align  4, 0x90
_main:                                  ## @main
    .cfi_startproc
## BB#0:                                ## %entry
    push    RBP
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset rbp, -16
    mov RBP, RSP
Ltmp4:
    .cfi_def_cfa_register rbp
    xor EAX, EAX
    pop RBP
    ret
    .cfi_endproc


.subsections_via_symbols

编辑:

我再次更改代码,这次工作,我不得不说编译器是如此聪明

#include <cstdio>

int main()
{
    char *a = new char[1024];

    for(int i = 0; i != 1024; ++i){
        printf("%c", a[i]);
    }

    delete []a;

    return 0;
}

的malloc

#include <cstdio>
#include <cstdlib> // pulls in declaration of malloc, free


int main()
{
    char *a = (char*)malloc(1024);

    for(int i = 0; i != 1024; ++i){
        printf("%c", a[i]);
    }

    free(a);

    return 0;
}

clang ++ -S -O3 -mllvm --x86-asm-syntax = intel -fno-exceptions main.cpp

汇编c

.section    __TEXT,__text,regular,pure_instructions
    .globl  _main
    .align  4, 0x90
_main:                                  ## @main
    .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    R14
    push    RBX
Ltmp6:
    .cfi_offset rbx, -32
Ltmp7:
    .cfi_offset r14, -24
    mov EDI, 1024
    call    _malloc
    mov R14, RAX
    mov EBX, 1
    xor EDI, EDI
    jmp LBB0_1
    .align  4, 0x90
LBB0_2:                                 ## %for.body.for.body_crit_edge
                                        ##   in Loop: Header=BB0_1 Depth=1
    movsx   EDI, BYTE PTR [R14 + RBX]
    inc RBX
LBB0_1:                                 ## %for.body
                                        ## =>This Inner Loop Header: Depth=1
    call    _putchar
    cmp EBX, 1024
    jne LBB0_2
## BB#3:                                ## %for.end
    mov RDI, R14
    call    _free
    xor EAX, EAX
    pop RBX
    pop R14
    pop RBP
    ret
    .cfi_endproc


.subsections_via_symbols

汇编c ++

    .section    __TEXT,__text,regular,pure_instructions
    .globl  _main
    .align  4, 0x90
_main:                                  ## @main
    .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    R14
    push    RBX
Ltmp6:
    .cfi_offset rbx, -32
Ltmp7:
    .cfi_offset r14, -24
    mov EDI, 1024
    call    __Znam
    mov R14, RAX
    mov EBX, 1
    xor EDI, EDI
    jmp LBB0_1
    .align  4, 0x90
LBB0_2:                                 ## %for.body.for.body_crit_edge
                                        ##   in Loop: Header=BB0_1 Depth=1
    movsx   EDI, BYTE PTR [R14 + RBX]
    inc RBX
LBB0_1:                                 ## %for.body
                                        ## =>This Inner Loop Header: Depth=1
    call    _putchar
    cmp EBX, 1024
    jne LBB0_2
## BB#3:                                ## %for.end
    test    R14, R14
    je  LBB0_5
## BB#4:                                ## %delete.notnull
    mov RDI, R14
    call    __ZdaPv
LBB0_5:                                 ## %delete.end
    xor EAX, EAX
    pop RBX
    pop R14
    pop RBP
    ret
    .cfi_endproc


.subsections_via_symbols
在删除缓冲区之前,c ++版本正在调用new和delete的程序集。 c ++程序集检查指针是否指向nullptr,如果是,则不删除 缓冲区;否则删除缓冲区。

2 个答案:

答案 0 :(得分:3)

您的汇编代码看起来似乎没有做任何事情。编译器检测到你没有在main中做任何重要的事情,并优化了除“return 0”之外的所有内容。您可以尝试禁用优化或打印指针a的值。

答案 1 :(得分:0)

鉴于您在命令行中指定了无异常,因此代码相同并不奇怪。查看-fno-exceptions和enabled启用之间的程序集差异。