C++中的return和exit区别
在main函数中,return和exit经常混用,两者的一个区别: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\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代码
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 |
C++中的return和exit区别的更多相关文章
- oracle 存储过程循环体中的return和exit区别:
oracle 存储过程循环体中的return和exit区别: (1) return 跳出整个循环,终止该循环, 后面的不再执行. 相当于 Java 中的break; (2) exit ...
- Linux编程return与exit区别
Linux编程return与exit区别 exit 是用来结束一个程序的执行的,而return只是用来从一个函数中返回. return return 表示从被调函数返回到主调函数继续执行,返回时可附 ...
- pl/sql中return和exit区别
经测试: 1.exit只能用于循环中,并且退出循环往下执行: 2.return可用于循环或非循环,并且退出整个程序模块不往下执行. declare i number :=1; j number :=1 ...
- C/C++中的return和exit
return:只是退出函数; ~是关键字. exit:是退出进程; ~是函数名. 整理自:https://www.cnblogs.com/cxchanpin/p/6927025.html
- c语言return与exit的区别
2013-09-0918:54:33 exit函数在头文件stdlib.h中,函数原型: void exit(int status); exit(0) 正常运行程序并退出程序. exit(1) 非正常 ...
- return 与 exit() 的区别
return是一个关键字,返回函数值:exit()是一个函数: return是语言级的:exit()是操作系统提供的函数: return表示函数退出:exit()表示进程退出: 非主函数中调用retu ...
- 【VS开发】Return与Exit的区别
1. exit用于结束正在运行的整个程序,它将参数返回给OS,把控制权交给操作系统:而return 是退出当前函数,返回函数值,把控制权交给调用函数. 2. exit是系统调用级别,它表示一个进程的结 ...
- return die exit 常用
die()停止程序运行,输出内容exit是停止程序运行,不输出内容return是返回值die是遇到错误才停止exit是直接停止,并且不运行后续代码,exit()可以显示内容.return就是纯粹的返回 ...
- lr中exit(-1)和return 0的区别
LR脚本实践:关于lr中exit(-1)和return 0的区别 exit(-1):从当前action里面exit(-1)所在行,当前迭代里面直接退出来,终止运行: return 0:忽略当前acti ...
随机推荐
- 搭建Tomcat应用服务器、tomcat虚拟主机及Tomcat多实例部署
一.环境准备 系统版本:CentOS release 6.6 (Final) x86_64 Tomcat版本:tomcat- JDK版本:jdk-8u25-linux-x64 关闭防火墙 软件包下载地 ...
- Jvm的体系结构
1.垃圾回收器 垃圾回收器(又称为gc):是负责回收内存中无用的对象(好像地球人都知道),就是这些对象没有任何引用了,它就会被视为:垃圾,也就被干掉了. 2.类装载子系统 一听名字,大家就知道,肯定是 ...
- 用python探索和分析网络数据
Edited by Markdown Refered from: John Ladd, Jessica Otis, Christopher N. Warren, and Scott Weingart, ...
- Delphi使用逍遥安卓模拟器
由于使用红鱼儿推荐的iTools安卓模拟器一打开virtualbox就消失,所以自己琢磨了使用逍遥安卓 首先在软件管理里面下载逍遥安卓,然后安装设置一下: 3.安装并启动虚拟机,Delphi IDE是 ...
- springboot maven 部署
1.在pom.xml文件中配置tomcat插件 <build> <plugins> <plugin> <groupId>org.springframew ...
- js中json的使用
- ELK收集Nginx|Tomcat日志
1.Nginx 日志收集,先安装Nginx cd /usr/local/logstash/config/etc/,创建如下配置文件,代码如下 Nginx.conf input { file { typ ...
- 判断URL是否能被链接
判断url是否能被正确链接 function checkUrl(url, name) { $.ajax({ url: url, type: "get", dataType : 'j ...
- pyton 模块之 pysmb 文件上传和下载(linux)
首先安装pysmb模块 下载文件 from smb.SMBConnection import SMBConnection conn = SMBConnection('anonymous', '', ' ...
- day34 并发编程之生产者消费者模型 队列
1.守护进程(了解) """ 守护进程 表示 一个进程b 守护另一个进程a 当被守护的进程a结束后 那么b也跟着结束了 就像 皇帝驾崩 妃子殉葬 应用场景 之所以开启子进 ...