一个没有返回值的函数

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

posted on 2010-07-18 01:06 role0523 阅读(5110) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


导航

<2010年7月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿

随笔档案

搜索

最新评论

  • 1. re: i++与++i
  • @role0523
    基本上是没有去区别的,有时候++i能被优化掉,但很多时候编译器能发现他们是一样的,所以没有区别。
  • --chaogu
  • 2. re: i++与++i
  • @chaogu
    忘记在谁的blog上看到在比较i++和++i哪个操作更高效,于是就看看他们汇编指令的条数。其实大多数时候都是一样的。
  • --role0523
  • 3. re: 数组越界的陷阱
  • @陈梓瀚(vczh)
    嵌入式项目中 vector还是比较慎用的
  • --role0523
  • 4. re: 数组越界的陷阱
  • 不如用vector代替你的if
  • --陈梓瀚(vczh)
  • 5. re: i++与++i
  • 用汇编表达了一个很早就被默认了的定理,好还是不好呢?
  • --chaogu

阅读排行榜

评论排行榜