在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区别的更多相关文章

  1. oracle 存储过程循环体中的return和exit区别:

    oracle 存储过程循环体中的return和exit区别:   (1) return 跳出整个循环,终止该循环, 后面的不再执行.     相当于 Java 中的break;   (2)  exit ...

  2. Linux编程return与exit区别

    Linux编程return与exit区别 exit  是用来结束一个程序的执行的,而return只是用来从一个函数中返回. return return 表示从被调函数返回到主调函数继续执行,返回时可附 ...

  3. pl/sql中return和exit区别

    经测试: 1.exit只能用于循环中,并且退出循环往下执行: 2.return可用于循环或非循环,并且退出整个程序模块不往下执行. declare i number :=1; j number :=1 ...

  4. C/C++中的return和exit

    return:只是退出函数;  ~是关键字. exit:是退出进程; ~是函数名. 整理自:https://www.cnblogs.com/cxchanpin/p/6927025.html

  5. c语言return与exit的区别

    2013-09-0918:54:33 exit函数在头文件stdlib.h中,函数原型: void exit(int status); exit(0) 正常运行程序并退出程序. exit(1) 非正常 ...

  6. return 与 exit() 的区别

    return是一个关键字,返回函数值:exit()是一个函数: return是语言级的:exit()是操作系统提供的函数: return表示函数退出:exit()表示进程退出: 非主函数中调用retu ...

  7. 【VS开发】Return与Exit的区别

    1. exit用于结束正在运行的整个程序,它将参数返回给OS,把控制权交给操作系统:而return 是退出当前函数,返回函数值,把控制权交给调用函数. 2. exit是系统调用级别,它表示一个进程的结 ...

  8. return die exit 常用

    die()停止程序运行,输出内容exit是停止程序运行,不输出内容return是返回值die是遇到错误才停止exit是直接停止,并且不运行后续代码,exit()可以显示内容.return就是纯粹的返回 ...

  9. lr中exit(-1)和return 0的区别

    LR脚本实践:关于lr中exit(-1)和return 0的区别 exit(-1):从当前action里面exit(-1)所在行,当前迭代里面直接退出来,终止运行: return 0:忽略当前acti ...

随机推荐

  1. 教你phpstudy如何搭建本地多站点

    经常做多个网站同时开发,如何才能在本地能使部署多个站点,今天就来分享一下如何用PHPstudy搭建本地多站点. 点击上图中的 其它选项菜单 ,就会弹出下面的对话框,然后点击 站点域名管理 然后在 网站 ...

  2. py库:把python打包成exe文件(pyinstaller)

    http://blog.csdn.net/be_quiet_endeavor/article/details/73929077 用Pyinstaller把Python3.4程序打包成可执行文件exe ...

  3. PHP安装Commposer

    一先把php加到环境变量里面测试 看一下版本号: 二,composer得安装注意安装的时候 php必须在5.59以上版本,openssl的扩展开启,pdo的扩展开启,mbstring的扩展开启 1,下 ...

  4. linux文件属性的10个字符各代表什么意思

    10个字符表示文件类别和权限,具体如下: 例: 第一个字符表示文件类别,代表的含义如下:-:普通文件d:目录文件b:块设备文件c:字符设备文件l:符号链接文件 后面9个字符代表3组访问权限:第1组的3 ...

  5. postgresql数据库varchar、char、text的比较

    名字 描述character varying(n), varchar(n) 变长,有长度限制character(n), char(n) 定长,不足补空白text 变长,无长度限制简单来说,varcha ...

  6. PHP和Redis实现在高并发下的抢购及秒杀功能示例详解

    抢购.秒杀是平常很常见的场景,面试的时候面试官也经常会问到,比如问你淘宝中的抢购秒杀是怎么实现的等等. 抢购.秒杀实现很简单,但是有些问题需要解决,主要针对两个问题: 一.高并发对数据库产生的压力二. ...

  7. vue 时间过滤

    1.过滤13位时间戳(以评论时间为例) filters : { formattime2: function (value) { //value为13位的时间戳 var timestamp = Date ...

  8. route命令详解

    1.   使用背景:需要接入两个网络,一个是部署环境所在内网环境,这个环境是上不了外网, 外网环境很可能是一个无线网络.如果两者都连接上,很可能导致有一方不能起作用,即外网或内网上不了,常常需要使用繁 ...

  9. Node2.js

    Node.js简单爬虫的爬取,也是跟着慕课网上抄的,网站有一点点改动,粘上来好复习嘛 var http = require('http') var cheerio = require('cheerio ...

  10. as3中的embed

    actionscript3允许把外部swf直接用Embed标记嵌入到主类中(当然用UrlLoader动态加载也行) 原 作者:菩提树下的杨过出处:http://yjmyzz.cnblogs.com 关 ...