勤能补拙,Expter

成都游戏Coder,记录游戏开发过程的笔记和心得!

关于 warning C4715问题。

介绍:
 
   关于warning C4715:not all control paths return a value
  (不是所有的控件路径都返回值).

问题:
    一个函数,不是所有路径都有返回值,如下:

    1) 基本数据类型
    对于函数的并不是每个分支都有返回值,那么这样警告会提示不是所有路径都有返回值。

int   test( int value )
{
     
if ( value > 0 ) return value;
}


   调用 int value = test( -1 );

   看下test的汇编代码.

关于8个程序寄存器一般只有esp寄存器作为入栈,出栈,调用和返回指令作为栈指针,其余

比如eax,exc等寄存器都没有固定的含义和固定值.
看下面test汇编代码.
int   test( int value )
{

; 4个寄存器入栈
; ebp 用于存放函数栈的栈顶指针
; esp 用于存放函数栈的栈底指针

004113A0  push        ebp              ;将寄存器ebp的内容压入程序栈
004113A1  mov         ebp,esp             ;保留esp寄存器
004113A3  sub         esp,0C0h             ;为该函数留出临时存储区
004113A9  push        ebx  
004113AA  push        esi  
004113AB  push        edi  

; 用0CCCCCCCCh初始化堆栈                
004113AC  lea         edi,[ebp
-0C0h]        ;lea直接寻址
004113B2  mov         ecx,30h             ;利用编译器的offset立即寻址
004113B7  mov         eax,0CCCCCCCCh         ;eax
=0CCCCCCCCh
004113BC  rep stos    dword ptr es:[edi]     ;根据edi的大小来重复指令执行次数

; 如果 cmp为真则把value的值保存到eax寄存器中
; 否则跳转到地址4113C7h,并没有对eax做处理

     
if ( value > 0 ) return value;
004113BE  cmp         dword ptr [value],
0 
004113C2  jle         test
+27h (4113C7h) 
004113C4  mov         eax,dword ptr [value] 
}


;各指针出栈,对应前面3条push

004113C7  pop         edi              ;弹出edi
004113C8  pop         esi              ;弹出esi
004113C9  pop         ebx              ;弹出ebx
004113CA  mov         esp,ebp             ;把esp重新指向ebp(函数栈的栈顶指

针,test函数栈顶)
004113CC  pop         ebp              ;ebp重新指向test调用函数返回地址
004113CD  ret


调用汇编代码

int value = test ( 1 );
004113FE  push        
1    
00411400  call        test (4110AFh) 
00411405  add         esp,4             ;Call test 函数时将压入栈数据,

由于只有一个参数,所以只有4字节
00411408  mov         dword ptr [value],eax 

当test 调用小于0时最后value指向的eax是一个0CCCCCCCCh,而对于基本数据类型大多value得到的是0CCCCCCCCh值.
如果我们的test函数:

int   test( int value )
{
     
if ( value > 0 ) return value;
     
return 0;
}

那么汇编代码会如下:

     if ( value > 0 ) return value;
004113EE  cmp         dword ptr [value],
0 
004113F2  jle         test
+29h (4113F9h) 
004113F4  mov         eax,dword ptr [value] 
004113F7  jmp         test
+2Bh (4113FBh) 
     
return 0;
004113F9  xor         eax,eax   ;将eax清零,作为返回值



   2 )如果返回的是一个引用对象
    

obj &  test( type value )
{
    
if( type2 ) return obj;
}


obj 
& ob = test( type1 );

   如果ob是个空引用的话,就出出错,关于这种出错是否可以通过什么方式避免呢?

   我觉得warning C4715就应该是error C4715.让开发者从最开始就避免这种错误的发生。

 

posted on 2011-04-09 12:52 expter 阅读(4535) 评论(3)  编辑 收藏 引用 所属分类: 工作笔记生活笔记算法与数据结构

评论

# re: 关于 warning C4715问题。 2011-04-09 13:33 Kevin Lynx

最后一个例子代码有点问题吧?可以让编译器将部分警告视为错误。
00411405 add esp,4 ;Call test 函数时将压入栈数据
准确的说这条语句是恢复堆栈,因为之前的push 1。默认的cdecl调用约定是调用者平衡堆栈。

win32汇编里约定eax作为返回值寄存器。  回复  更多评论   

# re: 关于 warning C4715问题。 2011-04-09 22:40 expter

@Kevin Lynx
最后一个例子代码有点问题吧?
有撒问题啊?

Obj & test( type value )
{
static Obj obj;
if( type2 ) return obj;
}

即使不是引用
obj ob = test( type1 );
这样也是错的。  回复  更多评论   

# re: 关于 warning C4715问题。 2011-04-10 19:25 Kevin Lynx

@expter
我指的是你文章里的test没有static Obj obj这句。  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理