4 ms·
> Fourth case - situations in which you have a scalar quantity, and do not care about positive or negative. This is actually where you have to be really carefu
by rbehrends 12y ago
> Fourth case - situations in which you have a scalar quantity, and do not care about positive or negative.
This is actually where you have to be really careful, because there can be corner cases surrounding zero. E.g.:
for (i=len-1; i>=0; i--) { ... }
Yes, either ints or unsigned numbers can overflow, but underflowing a natural number is much more common.
Don't take my word for it, ask Bjarne Stroustrup or Chandler Carruth: http://stackoverflow.com/questions/18795453/why-prefer-signed-over-unsigned-in-c http://stackoverflow.com/questions/18795453/why-prefer-signe...
- Nursie 12y agoIn that loop one should check that len is at least 1 first... I read that page, or at least some of it, it mostly seemed to be opinion rather than solid reason.
- rbehrends 12y ago> In that loop one should check that len is at least 1 first... No. The code is correct in that regard if you use int for i and len. Having to check len is an artifact of using unsigned. > I read that page, or at least some of it, it mostly seemed to be opinion rather than solid reason. I'm not talking about the comments. I'm talking about what Bjarne Stroustrup (the designer of C++) and Chandler Carruth (Google's LLVM lead) are saying in the video (and which is summarized in the top comment).
- Nursie 12y agoOnly if a sub 1 len is valid input, which it may not be. Either way the example is contrived and does not cover all other situations in which a scalar quantity is required. Not all are loop controllers. I did not watch the video, no time right now. The top comment tells us what they think, not why.
- pcwalton 12y agoI think this demonstrates a problem with C-style for loops (as opposed to iterators) more than unsigned integers.
- gnuvince 12y agoIt seems unreasonable to me that you need to write out the iteration variable 3 times in a C for-loop; I had a bug a couple weeks ago that took me longer to figure out than I care to admit. I wrote `for (int j = 0; i < N; ++j)`.
- rbehrends 12y agoThe problem lies with len-1 underflowing, not the loop that uses the result. For another example, to test congruence of x and y modulo m, you check if (x-y) % m == 0. This also blows up for unsigned integers if y > x unless m is a power of 2. Even iteration is not always over containers or some other structure in a way where the boundaries can be inferred and do not have to be computed, and not always in an order that is implemented by an iterator (for example, some in-place sorting algorithms).
- pcwalton 12y agoEven iteration over explicit ranges of unsigned integers can be handled by a Python range()-style iterator, without the risk of this bug (since the iterator itself is responsible for avoiding this gotcha).
- rbehrends 12y agoOnly if the language has ONLY iterators that are of the [closed, open) kind of interval. If you have, e.g., Smalltalk/Scala-like to:/to iterators (even if you have also iterators that exclude the upper end), you get the same problem in conjunction with unsigned integers (except that these languages use signed integers, so the problem doesn't show up).
- deleted 12y ago[deleted]
- detrino 12y agoIt's a problem with C for loops. There is really no good way to write a counting down loop using a for loop. The fundamental problem is that a for loop is: test a condition, run a loop body, then run a step function. This is suited to counting up loops but when counting down what you want is: test a condition, run a step function, then run a loop body. If you use while loops instead of for loops, you will see the two loops are symmetrical and there is no underflow for unsigned types. See http://ideone.com/1ABiCw http://ideone.com/1ABiCw