zoukankan      html  css  js  c++  java
  • C++中的return和exit区别

     

    main函数中,returnexit经常混用,两者的一个区别:return会执行statck unwinding,而exit不会。如果触发了信号,exit也同样不会做stack unwinding,除此之外异常如果没有相应的catch,也同样不会有栈展开(stack unwinding)。

    原因是C++编译器只会在遇到“}”或“return”时,才会安插栈展开代码,对于exit等则没这回事。

    #include <signal.h>

    #include <stdio.h>

    #include <stdlib.h>

     

    class X

    {

    public:

        X(int m): _m(m) { printf("X::ctor:%d ", m); }

        ~X() { printf("X::dtor:%d ", _m); }

     

    private:

        int _m;

    };

     

    int main()

    {

        X x(1);

    #if USE_EXIT

        exit(0);

    #if USE_RAISE

        raise(SIGSEGV);

    #else

        return 0;

    #endif

    }

     

    以上述代码为例,通过汇编,可很容易看出这两者的区别:

    1) return代码

    int main()

    {

        X x(1);

        return(0);

    }

     

    反汇编main函数,可以看到有调用~X

    0x08048474 <main+0>:    lea    0x4(%esp),%ecx

    0x08048478 <main+4>:    and    $0xfffffff0,%esp

    0x0804847b <main+7>:    pushl  0xfffffffc(%ecx)

    0x0804847e <main+10>:   push   %ebp

    0x0804847f <main+11>:   mov    %esp,%ebp

    0x08048481 <main+13>:   push   %ebx

    0x08048482 <main+14>:   push   %ecx

    0x08048483 <main+15>:   sub    $0x20,%esp

    0x08048486 <main+18>:   movl   $0x1,0x4(%esp)

    0x0804848e <main+26>:   lea    0xfffffff4(%ebp),%eax

    0x08048491 <main+29>:   mov    %eax,(%esp)

    0x08048494 <main+32>:   call   0x80484b6 <X>

    0x08048499 <main+37>:   mov    $0x0,%ebx

    0x0804849e <main+42>:   lea    0xfffffff4(%ebp),%eax

    0x080484a1 <main+45>:   mov    %eax,(%esp)

    0x080484a4 <main+48>:   call   0x80484da <~X>

    0x080484a9 <main+53>:   mov    %ebx,%eax

    0x080484ab <main+55>:   add    $0x20,%esp

    0x080484ae <main+58>:   pop    %ecx

    0x080484af <main+59>:   pop    %ebx

    0x080484b0 <main+60>:   pop    %ebp

    0x080484b1 <main+61>:   lea    0xfffffffc(%ecx),%esp

    0x080484b4 <main+64>:   ret

     

    2) exit代码

    int main()

    {

        X x(1);

        exit(0);

    }

     

    反汇编main函数,可以看到没有调用~X

    0x080484a4 <main+0>:    lea    0x4(%esp),%ecx

    0x080484a8 <main+4>:    and    $0xfffffff0,%esp

    0x080484ab <main+7>:    pushl  0xfffffffc(%ecx)

    0x080484ae <main+10>:   push   %ebp

    0x080484af <main+11>:   mov    %esp,%ebp

    0x080484b1 <main+13>:   push   %ecx

    0x080484b2 <main+14>:   sub    $0x24,%esp

    0x080484b5 <main+17>:   movl   $0x1,0x4(%esp)

    0x080484bd <main+25>:   lea    0xfffffff8(%ebp),%eax

    0x080484c0 <main+28>:   mov    %eax,(%esp)

    0x080484c3 <main+31>:   call   0x80484d4 <X>

    0x080484c8 <main+36>:   movl   $0x0,(%esp)

    0x080484cf <main+43>:   call   0x80483c8 <exit@plt>

    附:汇编指令

    call指令

    分两步:

    1) 将当前的IP或CS和IP压入栈中

    2) 转移(能实现短转移,它的书写格式同jmp指令)

    ret指令

    相当于pop IP

    retf指令

    相当于:

    1) pop IP

    2) pop CS

    lea指令

    把操作数OPRD的偏移地址传送到寄存器REG,语法:LEA REG, OPRD

  • 相关阅读:
    2015多校.Zero Escape (dp减枝 && 滚动数组)
    UVa-11809
    UVa-1588 Kickdown
    UVa-1587
    UVa-10340
    UVa-202
    UVa-1368
    UVa-232 Crossword Answers
    UVa-227
    UVa-455 Periodic Strings
  • 原文地址:https://www.cnblogs.com/aquester/p/10333238.html
Copyright © 2011-2022 走看看