为什么你不能检查errno是否等于ERANGE?
我一直在尝试使用strtol将char数组正确转换为long,检查是否存在溢出或下溢,然后对long执行int转换.一路上,我注意到很多代码看起来像这样
if ((result == LONG_MAX || result == LONG_MIN) && errno == ERANGE) { // Handle the error } 为什么你不能只说 if(errno == ERANGE) { // Handle the error } 根据我的理解,如果发生下溢或溢出,则在两种情况下都将errno设置为ERANGE.前者真的有必要吗?可以单独检查ERANGE是否有问题? 这就是我的代码现在的样子 char *endPtr; errno = 0; long result = strtol(str,&endPtr,10); if(errno == ERANGE) { // Handle Error } else if(result > INT_MAX || result < INT_MIN) { // Handle Error } else if(endPtr == str || *endPtr != ' ') { // Handle Error } num = (int)result; return num; 如果有前者的原因请告诉我. 解决方法
第一个代码片段是完全错误的,我稍后会解释原因,但首先我们需要一些背景知识.
errno是一个thread-local变量.当系统调用或某些库函数失败时,它将设置为非零值.系统调用成功时,它保持不变.因此它始终包含上次调用失败的错误号. 这意味着您有两个选择.在每次调用之前将errno设置为0,或者使用errno的标准习惯用法.这是标准习语的伪代码 if ( foo() == some_value_that_indicates_that_an_error_occurred ) then the value in errno applies to foo else foo succeeded and the errno must be ignored because it could be anything 大多数程序员都会使用标准习惯用法,因为在每次系统调用之前将errno设置为0是烦人的,重复的,烦人的,并且烦人地重复.更不用说你可能忘记在一个真实重要的地方将errno设置为0. 回到第一个代码段.这是错误的,因为strtol没有明确表示strtol失败的返回值.如果strtol返回LONG_MAX,则可能是发生错误,或者字符串实际包含数字LONG_MAX.无法知道strtol调用是成功还是失败.这意味着标准习惯用法(这是第一个代码片段试图实现的内容)不能与strtol一起使用. 要正确使用strtol,需要在调用之前将errno设置为0,如下所示 errno = 0; result = strtol( buffer,&endptr,10 ); if ( errno == ERANGE ) { // handle the error // ERANGE is the only error mentioned in the C specification } else if ( endptr == buffer ) { // handle the error // the conversion failed,i.e. the input string was empty,// or only contained whitespace,or the first non-whitespace // character was not valid } 请注意,某些实现为errno定义了其他非零值.有关详细信息,请参见适用的手册页 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 解决ajax提交form,点击保存按钮和点击回车效果不同的问题
- Oracle 11g merge into log error及并行注意事项
- PostgreSQL启动恢复通过checkpoint open wal文件
- c# – 查找用户管理的所有组
- 正则表达式去掉头尾空格
- ios – LaunchScreen.storyboard无法打开Main.storyboard导
- 正则表达式里的pattern和matcher
- Cocos2d-x3.3Final(9)RichText常用成员函数(C++)
- Flex addEventListener增加事件侦听函数时传递多个参数
- c# – 这个ASP.Net身份验证模型的安全性如何?