For Loop Exit Condition (size_t vs. int) [duplicate]

ε祈祈猫儿з 提交于 2021-01-28 00:41:43

问题


When I put the following in my program:

for (size_t i = VectorOfStructs.size()-1; i > 0; i--)

It works correctly but does "i" will never equal 0. So, I cannot access the first element (VectorOfStructs[0]).

If I change it to:

for (size_t i = VectorOfStructs.size()-1; i > -1; i--)

The program doesn't even enter the for loop! But, if I change it to the following:

for (int i = VectorOfStructs.size()-1; i > -1; i--)

It works exactly as I want it to (Iterates through all the elements).

So, my questions are:

(A) Why does the 2nd code snippet fail to execute?

(B) Why does the 3rd code snippet execute accordingly while the 2nd doesn't?

Any insight would be greatly appreciated!


回答1:


The second example uses size_t as type for i, which is an unsigned type, thus it can never have negative values; this also means that it cannot be properly compared with -1

But (int)-1 is bit-represented as 0xFFFFFFFF, which represents a rather large number (2^32-1) for size_t. i>0xFFFFFFFF can never be true, since 0xFFFFFFF is the largest value a size_t can ever hold.

The 3rd example uses signed int (which allows for negative numbers and therefore the test succeeds).

This one should work:

for (size_t i = VectorOfStructs.size(); i-- > 0;) {
  use(VectorOfStructs[i]);
}



回答2:


All loops go forward, even the ones that go backwards.

What you want is either this:

for (std::size_t i = 0, e = VectorOfStructs.size(); i != e; ++i)
{
    std::size_t const ri = e - i - 1;

    // use "VectorOfStructs[ri]"
}

Or better:

for (auto rit = VectorOfStructs.rbegin(); rit != VectorOfStructs.rend(); ++rit)
{
    // use "*rit"
}

(Your second snippet fails because i is unsigned, so -1 is converted to the same type as i and becomes the maximal representable value, so the comparison is always true. By contrast, i is signed in the third snippet.)




回答3:


In second one you comparing variable 'i' with -1 , and here it is of type size_t and size can not be in negative so it fails.

In third one , 'i' is integer type and integer has range from -32568 to +32567 (for int=2 byte in a system)

Overall size_t variable can not have negative values because a physical memory will have its existence in the system




回答4:


Why does the 2nd code snippet fail to execute?

size_t is unsigned, so it is by definition never negative. So your loop condition is always true. The variable "wraps around" to the maximum value.




回答5:


size_t is an unsigned type so -1 is the maximum value size_t can take. In the second snippet size_t can't be greater than this maximum value so the loop isn't entered.

On the other hand, int is a signed type so the comparison to -1 is as you expect.




回答6:


Int and size_t are both integer types but int can hold negatives as well as positives. int ranges from -2^31 -1 to 2^31 -1 while size_t ranges from 0 to 2^32 -1

Now, when you write something like int a = -1 it is indeed -1 but when you do so with size_t you get the max int 2^32 -1

So in the 2nd snippet no size_t value will ever exceed -1 as it really 2^32 -1

In the 3rd snippet the type compared is int and when int is compared to -1 it sees it as -1 so it executes the way you planned




回答7:


When the compiler sees i > -1 and notices that the subexpressions i and -1 have different types, it converts them both to a common type. If the two types (std::size_t and int) have the same number of bits, which appears to be the case for your compiler, the common type is the unsigned one (std::size_t). So the expression turns out to be equivalent to i > (std::size_t)-1. But of course (std::size_t)-1 is the maximum possible value of a size_t, so the comparison is always false.

Most compilers have a warning about a comparison that is always true or always false for reasons like this.




回答8:


Whenever you compare 'signed' and 'unsigned' the 'signed' values are converted to 'unsigned', first. That covers (#1) and (#2), having a problems with 'unsigned(0-1)' and 'some unsigned' > 'unsigned max'.

However, making it work by forcing a 'signed'/'signed' compare (#3), you loose 1/2 of the 'unsigned' range.

You may do:

for(size_t n = vector.size(); n; /* no -- here */ ) {
   --n;
   // vector[n];
}

Note: unsigned(-1) is on many systems the biggest unsigned integer value.



来源:https://stackoverflow.com/questions/31659368/for-loop-exit-condition-size-t-vs-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!