Related
(Sorry in advance, this question is probably very simple. I write code as a hobby and am just trying to wrap my mind around some things right now.)
I recently encountered a loop statement like (n is a previously set positive integer):
int cnt;
for(cnt=0; n; cnt++){
n &= n - 1;
}
If I understand correctly, the middle entry in a loop should be a condition, but n; does not seem to be a condition at all. Unless if it is understood as a bool (true if n!=0 and false if n==0). If this is the correct way to think about it, would the following code be perfectly equivalent to the above?
int cnt=0;
while(n>0){
n &= n - 1;
cnt++;
}
If yes, why would one choose the former style of writing this instead of the while loop? It seems to me that a while loop would be the most clear and intuitive choice here, so I wonder if there is any advantage in the for loop that I missed? Thanks for any suggestion!
If I understand correctly, the middle entry in a loop should be a condition, but n; does not seem to be a condition at all.
It is.
Unless if it is understood as a bool (true if n!=0 and false if n==0).
Yes.
If this is the correct way to think about it, would the following code be perfectly equivalent to the above?
Nearly; it's n != 0, not n > 0.
If yes, why would one choose the former style of writing this instead of the while loop?
People do silly things all the time, for all sorts of reasons!
It seems to me that a while loop would be the most clear and intuitive choice here
I agree.
I wonder if there is any advantage in the for loop that I missed?
Nope.
Well, not for this one. If the loop body were different, say with more complex logic and a continue statement or two, the behaviour of the program might be different (if you forgot to increment cnt on your new code path). But that's not the case here.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Whenever I need to break out from a for(unsigned int i=0;i<bound;++i) expression in C++, I simply set the index variable i=bound, the same way as described in this answer. I tend to avoid the break statement because, honestly, I have no good understanding of what it actually does.
Compare the two instructions:
for(unsigned int i=0;i<bound;++i) {
if (I need a break) {
break;
}
}
and
for(unsigned int i=0;i<bound;++i) {
if (I need a break) {
i=bound;
}
}
I speculate that the second method does one extra variable set and then one extra comparison between i and bound, so it looks more expensive, from performance point of view. The question is then is it cheaper to call break, then doing these two tests? Are the compiled binaries any different? Is there any instance, where the second method breaks, or can I safely choose either of these two alternatives?
Related: Does `break` work only for `for`, `while`, `do-while`, `switch' and for `if` statements?
Breaking out of a loop without a break statement [C]
Using break will be more future proof and more logical.
Consider the following example,
for (i = 0; i < NUM_OF_ELEMENTS; i++)
{
if(data[i] == expected_item)
break;
}
printf("\n Element %d is at index %d\n", expected_item, i);
But the second method won't be useful here.
There are three main technical differences that come to mind:
as other have stated, if your index variable is not confined to the for scope break leaves it intact, while your method destroys its content; when you are searching e.g. an array with break the code is more concise (you don't have to keep an extra variable to write down where you stopped);
break quits the loop immediately; your method requires you to execute the rest of the body. Of course you can always write:
for(int i=0; i<n; ++i) {
if(...) {
i=n;
} else {
rest of the loop body
}
}
but it adds visual and logical clutter to your loop;
break is almost surely going to be translated to a simple jmp to the instruction just following the loop (although, if you have block-scoped variables with a destructor the situation may be more complicated); your solution is not necessarily recognized by the compiler as equivalent.
You can actually see it here that gcc goes all the way to generate the code that moves n into i, while in the second case it jumps straight out of the loop.
On the stylistic side:
I find "your way" to be overly complicated and not idiomatic - if I encountered it in real code I would ask myself "why didn't he just use a break?", and then check twice to make sure that it's not like I'm missing some side effect and that the intent was actually just to jump out of the loop;
as other said, there's some risk of your inner assignment to go out of sync with the actual loop condition;
it doesn't scale when the loop condition becomes more complicated than a simple range check, both on the logic side (if the loop condition is complicated then tricking it can become more complicated) and on the performance side (if the loop condition is expensive and you already know you want to exit you don't want to check it again); this too can be circumvented by adding an extra variable (which is typically done in languages that lack break), but that's again extra distractions from what your algorithm is actually doing;
it doesn't work at all with range-based loops.
I prefer break; because it leaves the loop variable intact.
I frequently use this form while searching for something:
int i;
for(i=0; i<list.size(); ++i)
{
if (list[i] == target) // I found what I'm looking for!
{
break; // Stop searching by ending the loop.
}
}
if (i == list.size() ) // I still haven't found what I'm looking for -U2
{
// Not found.
}
else
{
// Do work with list[i].
}
Are the compiled binaries different?
Almost certainly yes. (although an optimizer may recognize your pattern, and reduce them to nearly the same)
The break; statement will likely be an assembly "jump" statement to jump to the next instruction outside the list, while leaving the control variable unchanged.
Assigning the variable (in non-optimized code) will result in an assignment to the control variable, a test of that variable, and then a resulting jump to end the loop.
As others have mentioned, assigning the variable to its final value is less future-proof, in case your loop condition changes in the future.
In general, when you say:
"I have no good understanding of what it actually does. (so I use a workaround)",
I respond with:
"Take the time to learn what it does! A main aspect of your job as a programmer is to learn stuff."
Using break to do this is idiomatic and should be the default, unless for some reason the rather obfuscatory alternative serves to set the stage for logic below. Even then I'd prefer to do the variable setup after the loop exits, moving that setting closer to its usage for clarity.
I cannot conceive of a scenario where the performance matters enough to worry about it. Maybe a more convoluted example would demonstrate that. As noted the answer for that is almost always 'measure, then tune'.
In adition to the break statement to exit a for or [do] while loop, the use of goto is permitted to break out nested loops, e.g.:
for (i=0; i<k; i++) {
for (j=0; j<l; j++) {
if (someCondition) {
goto end_i;
}
}
}
end_i:
This question already has answers here:
Correct implementation of min
(2 answers)
Closed 9 years ago.
The implementation of std::min on cppreference and in the original stl looks like this:
return (b < a) ? b : a;
But I think this is slightly more readable:
return (a < b) ? a : b;
Which makes me wonder: are both implementations equivalent? Is there a particular reason why it is implemented like it is?
The two different implementations would determine whether you choose the first or the second object as minimum if they are equal, which may make a difference for objects, if not for primitive types.
This, coupled with implementation of some other algorithms could have a larger impact. For example, if a sort algorithm uses min(a[i], a[j]) where i < j and a[i] and a[j] have the same value, the first implementation would result in no swap between the elements while the second does, making the sort unstable.
Note: As BoBTFish mentioned, the C++11 standard guarantees that both min and max return the left most minimum:
25.4.7:
3 Remarks: Returns the first argument when the arguments are equivalent
6 Remarks: Returns a copy of the leftmost argument when several arguments are equivalent to the smallest
The implementations are not the same. What will happen in either implementation if a and b are equal? One will return a reference to a one will return a reference to b. The values of course are identical. But consider a struct in which the compare function only cared about one value, but some other values were different. This could have dramatic implications on sorting functions attempting to guarantee a stable sort.
Ultimately it's a style choice, in the event of equality should we return the first or second parameter? However, now that this style choice has been made, that it remains the same is very important, this is why things like standards definitions exist!
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Search for "25.4.7" regarding maximum and minimum.
-- INCORRECT ANSWER -- SEE COMMENTS -- bb
FWIW, it hasn't been my observation that STL was written to be especially easy to read, necessarily, but it's beautifully simple; in this case, the only other possible way to get the same result would be
return (a <= b) ? a : b;
which would be one more character, and, IMHO, actually not as easy to read. Additionally, see #Shahbaz 's commentary above on sort stability--operations like min have a well-defined behavior for inclusivity and exclusivity.
TL;DR because "Less than" is not the same as "Less than or equal to"
See comments below--this answer would be correct as a macro in C but actually is incorrect in C++ for reasons explained in the comments below. I'm marking this as incorrect but leaving it up because the comments are useful and important to understand. I apologize if I confused the issue for anyone.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
When I was taking CS in college (mid 80's), one of the ideas that was constantly repeated was to always write loops which test at the top (while...) rather than at the bottom (do ... while) of the loop. These notions were often backed up with references to studies which showed that loops which tested at the top were statistically much more likely to be correct than their bottom-testing counterparts.
As a result, I almost always write loops which test at the top. I don't do it if it introduces extra complexity in the code, but that case seems rare. I notice that some programmers tend to almost exclusively write loops that test at the bottom. When I see constructs like:
if (condition)
{
do
{
...
} while (same condition);
}
or the inverse (if inside the while), it makes me wonder if they actually wrote it that way or if they added the if statement when they realized the loop didn't handle the null case.
I've done some googling, but haven't been able to find any literature on this subject. How do you guys (and gals) write your loops?
I always follow the rule that if it should run zero or more times, test at the beginning, if it must run once or more, test at the end. I do not see any logical reason to use the code you listed in your example. It only adds complexity.
Use while loops when you want to test a condition before the first iteration of the loop.
Use do-while loops when you want to test a condition after running the first iteration of the loop.
For example, if you find yourself doing something like either of these snippets:
func();
while (condition) {
func();
}
//or:
while (true){
func();
if (!condition) break;
}
You should rewrite it as:
do{
func();
} while(condition);
Difference is that the do loop executes "do something" once and then checks the condition to see if it should repeat the "do something" while the while loop checks the condition before doing anything
Does avoiding do/while really help make my code more readable?
No.
If it makes more sense to use a do/while loop, then do so. If you need to execute the body of a loop once before testing the condition, then a do/while loop is probably the most straightforward implementation.
First one may not execute at all if condition is false. Other one will execute at least once, then check the conidition.
For the sake of readability it seems sensible to test at the top. The fact it is a loop is important; the person reading the code should be aware of the loop conditions before trying to comprehend the body of the loop.
Here's a good real-world example I came across recently. Suppose you have a number of processing tasks (like processing elements in an array) and you wish to split the work between one thread per CPU core present. There must be at least one core to be running the current code! So you can use a do... while something like:
do {
get_tasks_for_core();
launch_thread();
} while (cores_remaining());
It's almost negligable, but it might be worth considering the performance benefit: it could equally be written as a standard while loop, but that would always make an unnecessary initial comparison that would always evaluate true - and on single-core, the do-while condition branches more predictably (always false, versus alternating true/false for a standard while).
Yaa..its true.. do while will run atleast one time.
Thats the only difference. Nothing else to debate on this
The first tests the condition before performing so it's possible your code won't ever enter the code underneath. The second will perform the code within before testing the condition.
The while loop will check "condition" first; if it's false, it will never "do something." But the do...while loop will "do something" first, then check "condition".
Yes, just like using for instead of while, or foreach instead of for improves readability. That said some circumstances need do while and I agree you would be silly to force those situations into a while loop.
It's more helpful to think in terms of common usage. The vast majority of while loops work quite naturally with while, even if they could be made to work with do...while, so basically you should use it when the difference doesn't matter. I would thus use do...while for the rare scenarios where it provides a noticeable improvement in readability.
The use cases are different for the two. This isn't a "best practices" question.
If you want a loop to execute based on the condition exclusively than use
for or while
If you want to do something once regardless of the the condition and then continue doing it based the condition evaluation.
do..while
For anyone who can't think of a reason to have a one-or-more times loop:
try {
someOperation();
} catch (Exception e) {
do {
if (e instanceof ExceptionIHandleInAWierdWay) {
HandleWierdException((ExceptionIHandleInAWierdWay)e);
}
} while ((e = e.getInnerException())!= null);
}
The same could be used for any sort of hierarchical structure.
in class Node:
public Node findSelfOrParentWithText(string text) {
Node node = this;
do {
if(node.containsText(text)) {
break;
}
} while((node = node.getParent()) != null);
return node;
}
A while() checks the condition before each execution of the loop body and a do...while() checks the condition after each execution of the loop body.
Thus, **do...while()**s will always execute the loop body at least once.
Functionally, a while() is equivalent to
startOfLoop:
if (!condition)
goto endOfLoop;
//loop body goes here
goto startOfLoop;
endOfLoop:
and a do...while() is equivalent to
startOfLoop:
//loop body
//goes here
if (condition)
goto startOfLoop;
Note that the implementation is probably more efficient than this. However, a do...while() does involve one less comparison than a while() so it is slightly faster. Use a do...while() if:
you know that the condition will always be true the first time around, or
you want the loop to execute once even if the condition is false to begin with.
Here is the translation:
do { y; } while(x);
Same as
{ y; } while(x) { y; }
Note the extra set of braces are for the case you have variable definitions in y. The scope of those must be kept local like in the do-loop case. So, a do-while loop just executes its body at least once. Apart from that, the two loops are identical. So if we apply this rule to your code
do {
// do something
} while (condition is true);
The corresponding while loop for your do-loop looks like
{
// do something
}
while (condition is true) {
// do something
}
Yes, you see the corresponding while for your do loop differs from your while :)
As noted by Piemasons, the difference is whether the loop executes once before doing the test, or if the test is done first so that the body of the loop might never execute.
The key question is which makes sense for your application.
To take two simple examples:
Say you're looping through the elements of an array. If the array has no elements, you don't want to process number one of zero. So you should use WHILE.
You want to display a message, accept a response, and if the response is invalid, ask again until you get a valid response. So you always want to ask once. You can't test if the response is valid until you get a response, so you have to go through the body of the loop once before you can test the condition. You should use DO/WHILE.
I tend to prefer do-while loops, myself. If the condition will always be true at the start of the loop, I prefer to test it at the end. To my eye, the whole point of testing conditions (other than assertions) is that one doesn't know the result of the test. If I see a while loop with the condition test at the top, my inclination is to consider the case that the loop executes zero times. If that can never happen, why not code in a way that clearly shows that?
It's actually meant for a different things. In C, you can use do - while construct to achieve both scenario (runs at least once and runs while true). But PASCAL has repeat - until and while for each scenario, and if I remember correctly, ADA has another construct that lets you quit in the middle, but of course that's not what you're asking.
My answer to your question : I like my loop with testing on top.
Both conventions are correct if you know how to write the code correctly :)
Usually the use of second convention ( do {} while() ) is meant to avoid have a duplicated statement outside the loop. Consider the following (over simplified) example:
a++;
while (a < n) {
a++;
}
can be written more concisely using
do {
a++;
} while (a < n)
Of course, this particular example can be written in an even more concise way as (assuming C syntax)
while (++a < n) {}
But I think you can see the point here.
while( someConditionMayBeFalse ){
// this will never run...
}
// then the alternative
do{
// this will run once even if the condition is false
while( someConditionMayBeFalse );
The difference is obvious and allows you to have code run and then evaluate the result to see if you have to "Do it again" and the other method of while allows you to have a block of script ignored if the conditional is not met.
I write mine pretty much exclusively testing at the top. It's less code, so for me at least, it's less potential to screw something up (e.g., copy-pasting the condition makes two places you always have to update it)
It really depends there are situations when you want to test at the top, others when you want to test at the bottom, and still others when you want to test in the middle.
However the example given seems absurd. If you are going to test at the top, don't use an if statement and test at the bottom, just use a while statement, that's what it is made for.
You should first think of the test as part of the loop code. If the test logically belongs at the start of the loop processing, then it's a top-of-the-loop test. If the test logically belongs at the end of the loop (i.e. it decides if the loop should continue to run), then it's probably a bottom-of-the-loop test.
You will have to do something fancy if the test logically belongs in them middle. :-)
I guess some people test at the bottom because you could save one or a few machine cycles by doing that 30 years ago.
To write code that is correct, one basically needs to perform a mental, perhaps informal proof of correctness.
To prove a loop correct, the standard way is to choose a loop invariant, and an induction proof. But skip the complicated words: what you do, informally, is figure out something that is true of each iteration of the loop, and that when the loop is done, what you wanted accomplished is now true. The loop invariant is false at the end, for the loop to terminate.
If the loop conditions map fairly easily to the invariant, and the invariant is at the top of the loop, and one infers that the invariant is true at the next iteration of the loop by working through the code of the loop, then it is easy to figure out that the loop is correct.
However, if the invariant is at the bottom of the loop, then unless you have an assertion just prior to the loop (a good practice) then it becomes more difficult because you have to essentially infer what that invariant should be, and that any code that ran before the loop makes the loop invariant true (since there is no loop precondition, code will execute in the loop). It just becomes that more difficult to prove correct, even if it is an informal in-your-head proof.
This isn't really an answer but a reiteration of something one of my lecturers said and it interested me at the time.
The two types of loop while..do and do..while are actually instances of a third more generic loop, which has the test somewhere in the middle.
begin loop
<Code block A>
loop condition
<Code block B>
end loop
Code block A is executed at least once and B is executed zero or more times, but isn't run on the very last (failing) iteration. a while loop is when code block a is empty and a do..while is when code block b is empty. But if you're writing a compiler, you might be interested in generalizing both cases to a loop like this.
In a typical Discrete Structures class in computer science, it's an easy proof that there is an equivalence mapping between the two.
Stylistically, I prefer while (easy-expr) { } when easy-expr is known up front and ready to go, and the loop doesn't have a lot of repeated overhead/initialization. I prefer do { } while (somewhat-less-easy-expr); when there is more repeated overhead and the condition may not be quite so simple to set up ahead of time. If I write an infinite loop, I always use while (true) { }. I can't explain why, but I just don't like writing for (;;) { }.
I would say it is bad practice to write if..do..while loops, for the simple reason that this increases the size of the code and causes code duplications. Code duplications are error prone and should be avoided, as any change to one part must be performed on the duplicate as well, which isn't always the case. Also, bigger code means a harder time on the cpu cache. Finally, it handles null cases, and solves head aches.
Only when the first loop is fundamentally different should one use do..while, say, if the code that makes you pass the loop condition (like initialization) is performed in the loop. Otherwise, if it certain that loop will never fall on the first iteration, then yes, a do..while is appropriate.
From my limited knowledge of code generation I think it may be a good idea to write bottom test loops since they enable the compiler to perform loop optimizations better. For bottom test loops it is guaranteed that the loop executes at least once. This means loop invariant code "dominates" the exit node. And thus can be safely moved just before the loop starts.
Looks like
while( condition ) {
//do stuff
}
is completely equivalent to
for( ; condition; ) {
//do stuff
}
Is there any reason to use the latter instead of the former?
There's no good reason as far as I know. You're intentionally misleading people by using a for-loop that doesn't increment anything.
Update:
Based on the OP's comment to the question, I can speculate on how you might see such a construct in real code. I've seen (and used) this before:
lots::of::namespaces::container::iterator iter = foo.begin();
for (; iter != foo.end(); ++iter)
{
// do stuff
}
But that's as far as I'll go with leaving things out of a for-loop. Perhaps your project had a loop that looked like that at one time. If you add code that removes elements of a container in the middle of the loop, you likely have to control carefully how iter is incremented. That could lead to code that looks like this:
for (; iter != foo.end(); )
{
// do stuff
if (condition)
{
iter = foo.erase(iter);
}
else
{
++iter;
}
}
However, that's no excuse for not taking the five seconds needed to change it into a while-loop.
Some compilers warn about constant loop conditions:
while (true) { /* ... */ } /* Warning! */
for (;;) { /* ... */ } /* No warning */
In the specific case of an infinite loop, I might choose a for loop over a while loop for that reason. But if the condition is not empty, I don't really see any benefit. My guess as to why it appeared in the mentioned project is that the code somehow evolved through maintenance, but was written in a more conventional way originally.
No. No. No.
Even if there were a microscopic performance difference, you'd have to be an end-stage Jedi performance tuner to have it matter enough to care.
Is there any reason to use the latter
instead of the former?
A misguided effort to impress your colleagues that you know that those two forms are equivalent.
A foolish maneuver to ensure "job security" by making your code as confusing as possible so that no one will ever want to change it.
The "w" key on your keyboard is broken.
It started life as a for loop with initializers and incrementing condition, and when the logic changed, the developer was too busy to change it.
It's possible to compile
for(INIT; CONDITION; UPDATE)
{
BODY
}
into
{
INIT
while(CONDITION)
{
BODY
UPDATE
}
}
UPDATE: The seemingly redundant extra scope is to cage any variable definitions in INIT, i.e. from for(int i = 0; ...). Thanks!
It's basically just a reordering of the expressions. So there's no reason to prefer one over the other, for performance reasons. I would recommend while() if possible, since it's simpler. If a simpler construct expresses what you want to do, I think that's the one to use.
As far as I know the two statements are optimized by the compiler into the same assember code anyway.. so no, there's no reason to do so - just personal preference.
I think "while" and "for" loops are meant for different idioms. The idiom of using "while" is "do something, while certain conditions are true". The idiom for "for" is "iterate over a certain range of elements"...
Whenever I read a code, I expect these idioms (and I think I am not alone). When I see "for" I understand, that someone is iterating over the certain range and I do not go into details. When I see the for cycle, used for another idiom (not the one, I expect), I get confused and have to go into details.
Anyway, it is very subjective...
In this case, I personally prefer the first loop as it is easier to write and read.
But if I have a loop that needs to some post statement, I'd use for loop like this:
for (; i < 10; i += 2)
There might be small compiler-dependent differences on the assembly level, but ideally both should behave exactly the same, and the former is more readable. So no, no reson to use the latter version other than nonconformism.
Compile both and check the resulting disassembly, if they are the same (which they probably are). Choose the one you find most readable.
if you want to do something a limited amount of times, then "for" let's you specify the constraint without jumbling it in with the logic inside your loop.
Keeping readability aside for a small while, there is usually no performance difference between the different loops. At least there is no significant difference.
For desktop applications you can chose based on Readability criteria. Refer to the other posts - e.g. looking at for loop someone thinks the incrementor is declared within the loop.
It seems for web applications e.g. client side scripting there might be a difference.
Check this site: http://www.websiteoptimization.com/speed/10/10-2.html
Run your own experiments and go by the results else stick by readability rules.
I can see 2 reasons, none of which I'd consider:
Only have 1 loop construct, but then Kristo's objection stands
write "for (; EVER;)", but then prefer a LOOP_FOREVER macro if really want this.
There really is no difference in C-ish languages between a for (;cond;) loop and a while loop. Generally what I do in C-ish languages is start off writing the loop as a "for" and change it into a "while" if I end up with that form. It is kinda rare though, as you are always iterating through something, and C lets you put any code you want in that last area.
It would be different if C had real (pre-computed iteration) for loops.
You might want to use a do-while loop instead of a for loop so the code is processed at least once before conditions are checked and met (or not).
I used to write some pretty cryptic C/C++ code. Looking back, I would probably do this in a while loop:
ifstream f("file.txt");
char c;
for(f.get(c); !f.eof(); f.get(c)) {
// ...
}
I guess my point is that for loops are usually shorter but less readable, if they're not used in the traditional sense of looping over a range.
This question has been answered - the language has a more natural construct for expressing what you want - you should use it. For example, I can certainly write this:
for (bool b = condition(); b; b = !b) {
/* more code */
}
or:
while (condition()) {
/* more code */
break;
}
instead of the more conventional:
if (condition()) {
/* more code */
}
But why? C (and all languages) have idioms and most of them make rational sense in terms of expressivity and expectation of meaning. When you dick with the idiom, your mess with the sensibilities of the person who has to read your code.