前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++中的return和exit区别

C++中的return和exit区别

作者头像
一见
发布2019-03-14 15:14:09
8430
发布2019-03-14 15:14:09
举报
文章被收录于专栏:蓝天蓝天

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

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

代码语言:javascript
复制
#include
#include
#include
class X
{
public:
X(int m): _m(m) { printf("X::ctor:%d\n", m); }
~X() { printf("X::dtor:%d\n", _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代码

代码语言:javascript
复制
int main()
{
X x(1);
return(0);
}

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

代码语言:javascript
复制
0x08048474 <main+0>:    lea    0x4(%esp),%ecx
0x08048478 :    and    $0xfffffff0,%esp
0x0804847b :    pushl  0xfffffffc(%ecx)
0x0804847e :   push   %ebp
0x0804847f :   mov    %esp,%ebp
0x08048481 :   push   %ebx
0x08048482 :   push   %ecx
0x08048483 :   sub    $0x20,%esp
0x08048486 :   movl   $0x1,0x4(%esp)
0x0804848e :   lea    0xfffffff4(%ebp),%eax
0x08048491 :   mov    %eax,(%esp)
0x08048494 :   call   0x80484b6
0x08048499 :   mov    $0x0,%ebx
0x0804849e :   lea    0xfffffff4(%ebp),%eax
0x080484a1 :   mov    %eax,(%esp)
0x080484a4 :   call   0x80484da <~X>
0x080484a9 :   mov    %ebx,%eax
0x080484ab :   add    $0x20,%esp
0x080484ae :   pop    %ecx
0x080484af :   pop    %ebx
0x080484b0 :   pop    %ebp
0x080484b1 :   lea    0xfffffffc(%ecx),%esp
0x080484b4 :   ret

2) exit代码

代码语言:javascript
复制
int main()
{
X x(1);
exit(0);
}

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

代码语言:javascript
复制
0x080484a4 <main+0>:    lea    0x4(%esp),%ecx
0x080484a8 :    and    $0xfffffff0,%esp
0x080484ab :    pushl  0xfffffffc(%ecx)
0x080484ae :   push   %ebp
0x080484af :   mov    %esp,%ebp
0x080484b1 :   push   %ecx
0x080484b2 :   sub    $0x24,%esp
0x080484b5 :   movl   $0x1,0x4(%esp)
0x080484bd :   lea    0xfffffff8(%ebp),%eax
0x080484c0 :   mov    %eax,(%esp)
0x080484c3 :   call   0x80484d4
0x080484c8 :   movl   $0x0,(%esp)
0x080484cf :   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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档