下面是函数读取行的一小段代码。
它怎么可能将bufsize
与((size_t)-1)/2
进行比较?
我想象过把一个变量与例如int
进行比较——这是不可能的;相反,我认为用INT_MAX是正确的。
那么,这段代码怎么能真正工作而不出错呢?
int c;
size_t bufsize = 0;
size_t size = 0;
while((c=fgetc(infile)) != EOF) {
if (size >= bufsize) {
if (bufsize == 0)
bufsize = 2;
else if (bufsize <= ((size_t)-1)/2)
bufsize = 2*size;
else {
free(line);
exit(3);
}
newbuf = realloc(line,bufsize);
if (!newbuf) {
free(line);
abort();
}
line = newbuf;
}
/* some other operations */
}
最佳答案
该代码依赖于关于比特的一些假设,然后对已知的最大siHeZT值做一个熟知的破解(前提是Sisixt不能容纳比寄存器更多的比特,在许多机器上是安全的赌注)。
首先它用1
位填充寄存器,然后将其转换为size_t
数据类型,这样比较就可以工作了。只要该寄存器的位数大于size_t
数据类型,则未使用的1
位(如果有)将被截断,并且您将得到可以容纳size_t
位的最大无符号数。
在你有了它之后,它除以两个以得到那个数字的一半,并进行比较,看看它是否安全增加尺寸而不超过“最大”size_t
。但到那时,它正在划分一个size_t
数据类型,并比较两个size_t
数据类型(类型安全操作)。
如果你真的想移除这个小魔法(好吧,这不是我见过的最糟糕的小魔法例子)。考虑以下片段
else if (bufsize <= ((size_t)-1)/2)
bufsize = 2*size;
可以替换为
else if (bufsize <= (MAX_SIZE/2)
bufsize = 2*size;
而且不需要强制转换就可以保证类型安全,而且可读性更强。
关于c - size_t用作公式中的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12222249/