如果在返回值為int的函數里,漏掉return,會發生什么情況?
編譯工具:Code::Blocks 10.05,代碼如下所示
#include <cstdio>
int f()
{
}
int main ()
{
printf("%d ",f());
printf("%d ",f());
printf("%d ",f());
return 0;
}
編譯時,提示
In function 'int f()':|
warning: no return statement in function returning non-void|
但是能編譯
Debug版本下結果如下:
1 2 2
Release版本下結果
0 0 0
下面分析一下為什么為發生這種情況:
從code:: blocks里面看到的 函數f的匯編代碼
00401318 push %ebp
00401319 mov %esp,%ebp //正確的似乎是 mov %ebp %esp
0040131B leave
0040131C ret
如果函數f()如下定義
int f()
{
return 100;
}
則匯編代碼是
00401318 push %ebp
00401319 mov %esp,%ebp
0040131B mov $0x64,%eax
00401320 leave
00401321 ret
接下來我們看一下整個main函數的匯編代碼
00401322 push %ebp
00401323 mov %esp,%ebp
00401325 and $0xfffffff0,%esp
00401328 sub $0x10,%esp
0040132B call 0x401770 <__main>
00401330 call 0x401318 <f()>
00401335 mov %eax,0x4(%esp)
00401339 movl $0x403024,(%esp)
00401340 call 0x4019ac <printf>
00401345 call 0x401318 <f()>
0040134A mov %eax,0x4(%esp)//將返回值傳遞給%esp+0x04
0040134E movl $0x403024,(%esp)
00401355 call 0x4019ac <printf>
0040135A call 0x401318 <f()>
0040135F mov %eax,0x4(%esp)
00401363 movl $0x403024,(%esp)
0040136A call 0x4019ac <printf>
0040136F mov $0x0,%eax
00401374 leave
00401375 ret
從中我們可以看出,函數f()是將返回值通過EAX寄存器中,傳遞給調用它的代碼。
如過我們漏掉了return intVal語句,在Debug模式下可能會導致,調用f()的代碼得到的是上次的其他函數被調用的返回值。
在進入main之后EAX通常會被初始化為0x01.所以第一個f() 返回值為1.
printf 打印了“1 ”兩個字符之后,返回值為2,所以第二個f()返回值為2。
printf 打印了“2 ”兩個字符之后,返回值為2,所以第三個f()返回值為2。
在Release版本下,函數f()被優化,printf直接打印數字0。
401320: push %ebp
401321: mov %esp,%ebp
401323: and $0xfffffff0,%esp
401326: sub $0x10,%esp
401329: call 0x401760
40132e: movl $0x0,0x4(%esp)
401335:
401336: movl $0x403024,(%esp)
40133d: call 0x40199c
401342: movl $0x0,0x4(%esp)
401349:
40134a: movl $0x403024,(%esp)
401351: call 0x40199c
401356: movl $0x0,0x4(%esp)
40135d:
40135e: movl $0x403024,(%esp)
401365: call 0x40199c
40136a: xor %eax,%eax
40136c: leave
40136d: ret