7 ms·
The terminal operation on the clever code compares the size_t to -1. But if it's unsigned this will never be true either, and so the test may be optimised away.
by alblue 11y ago
The terminal operation on the clever code compares the size_t to -1. But if it's unsigned this will never be true either, and so the test may be optimised away.
This probably demonstrates the point where clever code is more likely to have bugs ...
- gpvos 11y agoAre you really sure? I think the -1 will be coerced to unsigned int, instead of the other way around. That would make it work.
- knodi123 11y agowhat does it mean for -1 to be coerced into something unsigned? Wouldn't that be equivalent to 1? I, too, fail to understand how this is clever. Can someone enlighten me?
- zhang3r 11y ago-1 in 2's complement is actually MAX_INT in unsigned. Since numBurritos is also an unsigned int it would never exceed MAX_INT making this approach work.
- masklinn 11y ago`-1` will underflow, so you'll effectively have a SIZE_MAX. The counting down will similarly underflow, reach SIZE_MAX and stop the iteration.
- untothebreach 11y agoWouldn't it be clearer to just put `i != SIZE_MAX` then? I understand that anyone experienced with C probably wouldn't be confused by this, but you might as well sacrifice a couple characters in exchange for saving brain cycles, right?
- masklinn 11y agoI don't know if it'd be clearer. It'd be a better representation of what actually happens but would read very strangely. `!= -1` would make a reader think "shouldn't go below 0" and only on closer inspection would you wonder what actually happens, `!= SIZE_MAX` would probably make any reader stop and scratch their head. Whether that's a good thing is up for debate.
- plonh 11y agoif you are thinking about "<0" on an unsigned type, you better be scratching your head already.
- Lagged2Death 11y agoI'd expect anyone experienced with C would say that making such casual, deliberate use of the underflow for such a trivial purpose is pretty foolish, the mark of a developer too clever for his own good. I thought the author was perhaps suggesting this with sarcasm: "Wizened sourcerers" and "full clever." But maybe not. C's variable promotion system is invisible and silent and in my experience a frequent source of bugs in exactly this case (tests in for loops), which is why there's enough meat here for a blog post. It's usually easy to avoid the promotion issue by using the same type for the loop variable and its test condition. In cases like this, sometimes it's better to just use a straightforward and obvious while() loop instead of a correct but tortured for() loop. That makes the relationship between the loop variable updates and the loop body controllable and explicit.
- lorenzhs 11y agoIn C++, underflows of unsigned types are specified in the Standard. -1 is equivalent to the largest value your unsigned type can hold. This means that you can rely on this behaviour.
- cperciva 11y agoIt depends on the relative sizes of size_t and int. If size_t is at least as large as int, the coercion goes in favour of size_t.
- Lagged2Death 11y agoBut if it's unsigned this will never be true either... Conceptually, it works through promotion. -1 is cast to unsigned/size_t before the test, which then succeeds. At the assembly level, a 32-bit -1 is 0xFFFFFFFF, which is also the result of the underflow of i, so it works at that level, too. At any rate, it worked in the compiler I tried it with.
- eximius 11y agoAs everyone has so aptly explained, it probably will work. But it is certainly not obvious that it works and should probably be avoided (unless you are a 'wizened sorcerer').