本文共 2059 字,大约阅读时间需要 6 分钟。
c++函数返回值编写规范问题
笔者在使用c++进行编码时,发现编译器在对c/c++函数进行编译的时候存在缺陷。测试的编译器包括vs2010、vs2015、vc++ 6.0、gcc等。编译器在对函数进行编译的时候,并未对函数是否能正常的返回做判断,从而可能导致函数的返回数值是一个不确定的值的逻辑问题。
问题示例代码
#includeusing namespace std;int test() { int i = 0; if (i) { return 1; } return 0;}void main() { cout << test() << endl;}
改代码输出的值为0,比较易懂。但是当把test()函数中的return 0;注释掉之后,按照正常的理解,编译器应该出现报错的问题,但是在以上说明的编译器中均未出现报错。但是输出内容变为随机值。
问题分析
查看汇编代码可以发现,在函数结束的时候,并未对eax进行特殊的操作,从而导致调用函数以为eax中存储的为返回值,从而引发了错误。所以导致该问题的根本原因应该是编译器无法检测所有的返回分支是否可以正确返回,从而导致代码在返回时出现返回内容随机的问题。汇编代码如下:
41: int test() { 0032EFE3 81 EC CC 00 00 00 sub esp,0CCh 0032EFE9 53 push ebx 0032EFEA 56 push esi 0032EFEB 57 push edi 0032EFEC 8D BD 34 FF FF FF lea edi,[ebp-0CCh] 0032EFF2 B9 33 00 00 00 mov ecx,33h 0032EFF7 B8 CC CC CC CC mov eax,0CCCCCCCCh 0032EFFC F3 AB rep stos dword ptr es:[edi] //初始化本函数使用的临时栈空间。 42: int i = 0; 0032EFFE C7 45 F8 00 00 00 00 mov dword ptr [i],0 //将局部变量i赋值为0 43: if (i) { 0032F005 83 7D F8 00 cmp dword ptr [i],0 0032F009 74 05 je test+30h (032F010h) //执行返回,跳转到恢复栈空间 44: return 1; 0032F00B B8 01 00 00 00 mov eax,1 45: } 46: // return 0; 47: 48: } 0032F010 5F pop edi //恢复栈空间 0032F011 5E pop esi 0032F012 5B pop ebx 0032F013 8B E5 mov esp,ebp 0032F015 5D pop ebp 0032F016 C3
问题解决
为了防止出现问题,应当在所有的分支处都写上return语句,防止函数出现无法预期的错误。即使是指定分支一定可以返回的情况下,也最好在最后一句写上return,以防出现无法预估的问题。
调试器中对string进行监控,输出的内容可能并非真正的内容
在使用visual studio对程序进行调试的时候,下方的监控变量是我们经常使用的一个工具,但是今天笔者发现,在对变量进行监控的时候,可能出现vs给我们的输出并非变量的真实值的问题。
示例问题代码
代码见本人github,
问题分析
如下图,将断点下在对应的位置,result是一个string 类型,s[group_len*j+i]为’p’,执行该语句后,result应该由”pinalsigyahr”变为”pinalsigyahrp”。
当执行对应语句后,调试器的结果如下图所示,result的值仍然为”pinalsigyahr”没有发生变化。笔者第一次调试的时候以为是’p’没有增加到对应的位置。但是当打开result的内存进行详细检查的时候,发现结果如下图所示:
在result[12]的位置出现了一个0。因为在定义字符串的时候,在通常我们以’\0’为字符串的结尾,所以在此处visual studio的做法为以’\0’为结尾对字符串进行输出。该方案在理解上没有什么问题,但是笔者个人认为,string类型的话有对应的长度字符,所以应当以长度为标准对字符串进行输出比较好,’\0’做结尾是因为c语言中char *只有一个地址,并无长度标识,所以才总是以’\0’为结尾,所以应当区别对待。问题解决
在vs中,对字符串的显示均为以’\0’为结尾的,无论是string或者是char *。但是当类型为string的时候,最长可以取到string的长度,当string中出现0的时候,vs的窗口将无法自动输出真实的字符串,我们只能通过查看详细的内存对其进行操作。
转载地址:https://blog.csdn.net/meanong/article/details/80107959 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!