首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

一个类型转换唤起的Bug

2013-03-28 
一个类型转换引起的Bug最近有个bug实在让人抓狂,仅仅是由于一个简单的类型强转导致的,这里给大家讲讲。这是

一个类型转换引起的Bug
        最近有个bug实在让人抓狂,仅仅是由于一个简单的类型强转导致的,这里给大家讲讲。
这是pwrite系统调用的接口说明,我们关注最后一个参数:

int storage_write_meta_info(int fd, void *data, int unit){    ...    off_t     offset;    int       length;    ssize_t   n;    lenght = sizeof(struct xxx);    offset = unit * length;    n = pwrite(fd, data, length, offset);    ...}
        运行环境是CentOS x86_64,off_t的实际类型是long,8字节。程序在跑了很长一段时间后,遇到pwrite返回了-1,errno为(22: Invalid argument)。有经验的同学可能已经看出了问题:        当两个int类型相乘(即代码中的unit * length)发生溢出时,最后的结果已经产生,并截断为int类型保存在某处。这样这个被截断的错误值就赋给了offset,两者的相乘行为完全无视左值offset的类型。怎么处理好呢?只需要对其中任何一个相乘的变量做一个强转,即:offset = (off_t)unit * length 或者 offset = unit * (off_t)length 或者 offset = (off_t)unit * (off_t)length
        不过之前的代码pwrite就没有报错(但不一定就是正确):        offset = uint * sizeof(struct xxx);        因为sizeof的返回值是size_t,它的真面目是unsigned int,这里相当于换成了int * unsigned int,运算的结果被看做是一个unsigned int类型,碰巧没有越界罢了。
        所以这里告诫大家,在程序里面涉及很多不同类型的参数之间转换的时候,一点要谨慎,小心。最好的建议就是别整那么多类型!

热点排行