Here is a short snippet of a function reading lines.
How is that possible that it compares bufsize with ((size_t)-1)/2 ?
I imagined comparing a variable to eg. int – that is just impossible; to INT_MAX on the contrary it is correct, I think.
So how can that code actually work and give no errors?
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 */
}
The code relies on some assumptions about bits and then does a well known hack for finding the maximum size_t value (provided that size_t doesn’t accommodate more bits than the register, a safe bet on many machines).
First it fills a register up with
1bits, then it casts it into asize_tdata type, so the comparison will work. As long as that register is larger in number of bits than thesize_tdata type, then the (if any) unused1bits will be truncated, and you will get the largest unsigned number that can fit insize_tbits.After you have that, it divides by two to get half of that number, and does the comparison to see if it seems to be safe to increase size without going over the “maximum”
size_t. but by then, it’s dividing asize_tdata type, and comparing twosize_tdata types (a type safe operation).If you really wanted to remove this bit-wizardy (ok, it’s not the worst example of bit wizardy I’ve seen). Consider that the following snippet
could be replaced with
and be type safe without casting and more readable.