[英]size_t used as a value in a formula
Here is a short snippet of a function reading lines. 这是功能阅读线的简短片段。 How is that possible that it compares bufsize
with ((size_t)-1)/2
? 它如何将bufsize
与((size_t)-1)/2
?
I imagined comparing a variable to eg. 我想象过将变量与例如。 int
- that is just impossible; int
那是不可能的; to INT_MAX on the contrary it is correct, I think. 我认为与INT_MAX相反是正确的。 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 */
}
(size_t)-1
This is casting the value -1
to a size_t
. 这size_t
值-1
强制转换为size_t
。 (type)value
is a cast in C. (type)value
是C语言中的强制(type)value
。
Since size_t
is an unsigned type, this is actually the maximum value that size_t
can hold, so it's used to make sure that the buffer size can actually be safely doubled (hence the subsequent division by two). 由于size_t
是无符号类型,因此实际上是size_t
可以容纳的最大值,因此用于确保缓冲区大小实际上可以安全地翻倍(因此,随后的二分之一)。
(size_t)-1
casts -1
to the type size_t
, which results in SIZE_MAX
(a macro defined in stdint.h ), the maximum value that the size_t
type can hold. (size_t)-1
铸-1
的类型size_t
,这导致SIZE_MAX
(在stdint.h中定义的宏),该最大值size_t
类型可以容纳。
So the comparison is checking whether bufsize
is less than or equal to one half the maximum value that can be contained in a size_t
因此,比较是检查bufsize
是否小于或等于size_t
可以包含的最大值的一半。
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). 该代码基于一些有关位的假设,然后进行众所周知的破解以找到最大size_t值(前提是size_t所容纳的位不多于寄存器,这在许多机器上都是安全的选择)。
First it fills a register up with 1
bits, then it casts it into a size_t
data type, so the comparison will work. 首先,它用1
位填充一个寄存器,然后将其转换为size_t
数据类型,因此比较将起作用。 As long as that register is larger in number of bits than the size_t
data type, then the (if any) unused 1
bits will be truncated, and you will get the largest unsigned number that can fit in size_t
bits. 只要该寄存器的位数大于size_t
数据类型的位数,那么(如果有的话)未使用的1
位将被截断,并且您将获得可以容纳在size_t
位中的最大无符号数。
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
. 获得该值之后,它将除以2得到该数字的一半,然后进行比较以查看在不超过“ maximum” size_t
情况下增大大小似乎是安全的。 but by then, it's dividing a size_t
data type, and comparing two size_t
data types (a type safe operation). 但是到那时,它将划分一个size_t
数据类型,并比较两个size_t
数据类型(一种类型安全的操作)。
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 考虑以下代码段
else if (bufsize <= ((size_t)-1)/2)
bufsize = 2*size;
could be replaced with 可以替换为
else if (bufsize <= (MAX_SIZE/2)
bufsize = 2*size;
and be type safe without casting and more readable. 并且类型安全, 无需强制转换且更具可读性。
The size_t
in ((size_t)-1)/2)
is simply being used as a cast: casting -1
to size_t
. 所述size_t
在((size_t)-1)/2)
被简单地被用来作为铸:铸造-1
至size_t
。
The trick here is that size_t
is unsigned, so the cast (size_t) -1
will be converted to the maximum value of size_t
, or SIZE_MAX
. 这里的窍门是size_t
是无符号的,因此(size_t) -1
转换(size_t) -1
将转换为size_t
的最大值,即SIZE_MAX
。 This is useful in the context of the loop. 这在循环的上下文中很有用。 However, I'd prefer to see SIZE_MAX
used directly rather than this trick. 但是,我更希望直接使用SIZE_MAX
,而不是这种技巧。
size_t isn't being interpreted as a value, it's being used to cast the value of negative one to the type size_t. size_t不会被解释为值,而是用于将负1的值强制转换为type_t类型。
((size_t)-1)/2
is casting -1 to a size_t and then dividing by 2. 将-1转换为size_t,然后除以2。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.