简体   繁体   English

size_t用作公式中的值

[英]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)被简单地被用来作为铸:铸造-1size_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM