如果在返回值为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