size_t 数据类型深思

8 篇文章 0 订阅
4 篇文章 0 订阅

size_t 类型是一种跨平台用于计数的数据类型,它能表示的数据范围非常大:当前平台的 unsiged 整数。这也道出了它的本质:无符号整数。

在最近一个项目中,由于系统经常抛出 warning,int 与 size_t 比较大小,形如:

for(int i = 0;i < s.size();++ i)

{

}

这本身是没有问题的。但是由于不爽 warning,就萌发了将所有计数变量都改为 size_t 类型,于是开始了重构之路。改进的过程倒也不麻烦,

改完之后少了很多 warning,但也多了一些 warning 出来,一眼就能看出是类型的不匹配,容易解决。

于是顺利地解决完了,Release 程序后,运行,结果程序卡死,直接退出了,attach 进程进入调试模式后,才发现具体原因。

另一个很诡异的 bug 是,在调用模式下程序正确运行,而在 release 模式下却运行出错,检查了好长时间,才发现原因所在。

以下列出这次发现的问题及思考:


使用 size_t 数据类型可能犯一些隐藏很深的错:

1.逆序遍历:
size_t ncount = 1000;
for(;ncount > 0;-- ncount)
{
   //do something
}
这将是一个死循环,因为 ncount 为 0 时,--ncount 将使得 ncount 变为最大的 size_t 值,它是无符号整数。


解决办法有多种,如改逆序为正序遍历。或者这样:
for(;;-- ncount)
{
   //do something
   if(0 == ncount)
   {
     break;
   }
}


2.判断失误:
size_t ncount;
//do something to chang ncount
size_t x = 100;
if(ncount -1 > x)
{
   //so something
}
这个判断将会是错误的,同样会因为 ncount 为 0 时,它减去一个数将不会使得它变为负数。
可以这样解决:
if(ncount > 1+x)
{
   //so something
}


3.size_t 与 int 比较大小
size_t n = 100;
size_t m = -3;
assert(n > m); //断言将不通过
这是因为,无符号与有符号整数比较大小时,会统一将两个数字都转化为无符号整数再比较,而 -3 的二进制首位为 1,则对应的无符号位非常大
显然断言不成立。


总的来说:
一个 size_t 类型的数据减去一个数时需要十分注意,如果从逻辑上来讲,这个值应该存在为负的情况则将导致错误的行为。
一个 size_t 类型的数据与有符号整数比较大小也要十分注意,它们往往在编译时会导致 warning ,正确的改进它们是必须的。

绝对不要忽略掉编译器的 warning,它们都值得一看,如果说编译期给出的 error 能帮你消除明显的错误,而 warning 则是给你机会让你处理一此隐藏的,往往导致大问题的错误。绝对要认真检查每一个 warning ,并且消灭它!


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值