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 |
相關文章
- exit和return的區別
- 解析php中die(),exit(),return的區別PHP
- exit(0)與exit(1)、return的區別
- js中return、return true、return false的區別JSFalse
- python中 os._exit() 和 sys.exit(), exit(0)的用法和區別Python
- ruby中proc和lambda的return區別
- CSS 中 stopPropagation, preventDefault 和 return false 的區別CSSFalse
- system.exit(0)和system.exit(1)的區別
- oracle的exit、return、continueOracle
- Python教程:return和yield的區別Python
- C++中運算子 &和&&、|和|| 的區別C++
- onclick="return check()" 和 onclick="check()" 區別
- C++中 struct 和 class 的區別C++Struct
- C++中struct 和 class的區別C++Struct
- return,continue和break之間的區別
- js跳出迴圈的方法區別( break, continue, return ) 及 $.each 的(return true 和 return false)...JSFalse
- Break,Continue,Return的區別
- C++中break和continue的用法和區別C++
- C++中L和_T()之區別C++
- c++中&和&&有什麼區別C++
- C#中continue、return、break的區別及作用C#
- break,continue,return區別
- preventDefault()與return false區別False
- 'return await promise' 與 'return promise' 這細微的區別AIPromise
- Environment.Exit(0) 、Application.Exit() 、this.Close() 、this.Dispose()的區別APP
- C和C++區別C++
- C++中vector*和vector有什麼區別C++
- 引用的例子 C C++ 中區別C++
- c++中指標和引用的區別?C++指標
- C++中指標和引用的區別C++指標
- C++和java多型的區別C++Java多型
- C/C++——sizeof和strlen的區別C++
- mysql中!=和is not的區別MySql
- JavaScript中for in 和for of的區別JavaScript
- mysql中“ ‘ “和 “ ` “的區別MySql
- Js中for in 和for of的區別JS
- JavaScript中==和===的區別JavaScript
- C與C++中struct使用的區別C++Struct