Using != with counter controlled loops


Using != with counter controlled loops



Last question for today all...I will get back with tomorrow..I have a lot to follow up on...

I am looking in Reilly Java text- talking about counter controlled loop patterns..(does not matter what language..)

The author for counter controlled loops (for, while, etc) and with nesting loops...uses the != for test...Now I realize != is used for certain situations with event controlled loops-like sentinel or EOF type of loops- but to me- using it with a counter controlled loop is a bad idea...very prone to errors..

Examples:

x = 0; while (x != 100) {    y = 0;   while (y != 100) {     ...    y++;  }   x++; } 

Would it be better to just say..using the other relational operators...

x = 0; while (x < 100) {   //or even better some defined constant...    y = 0;   while (y < 100) {     ...    y++;  }   x++; } 

Which from what I have seen is usually the way presented in texts..classes.etc..

Once again- would all you considered this bad- or just a different way of doing it... Thanks...




C# generics compared to C++ templates [duplicate]

1:



Looking for a bitwise operator
as other answers have shown,
while(i < 100) is safe*,
while(i != 100) is precise**..
Interprocess Communication between C++ app and Java App in Windows OS environment
As an aside, you may want to try while(i++ < 100) or for(i = 0; i < 100; ++i) instead of the simpler while loop you have shown--forgetting to increment the counter at the end of the loop is a real pain.


Converting simple C++ code to C# automatically
Note that, if i=0, i++ will equal 0, and then increment i for next time, and ++i will increment i and then equal 1, so for while(i++ < 100), the postfix ++ operator is necessary..
How to call c++ functionality from java
Also note, that if i was 0 when it got tested in the condition, then it will be 1 in the loop body (for the while example), so if i is an index for an array or something, and not just keeping track of loop iterations, you'd be better to stick with just a for loop (which increments i after each iteration)..
Marshaling from C# to C++

.
Can we take advantage of the type system to make programs more secure?
*: safe here meaning less likely to enter an infinite loop.


Marshalling a struct containing c-strings
It is also unsafe in that it can hide potential errors, if the loop isn't trivial. **: precise in that if it doesn't do exactly what you expect it to, it will fail, and you will notice.

Some other answers have also described how to protect you from errors even more in this kind of loop..


2:


You want your loop condition to be the exact inverse of the desired post-condition..
i= 0; while( i != 100 ) {     i += 1; } assert i == 100; 
You can trivially see that the loop post-condition exactly matches the loop termination condition.

No mysteries.. Further, you can prove from the initial condition and the body that it will reach 100 without "somehow" magically skipping a value.. In the case when you have a really complex loop body, that simple parallel structure is essential.. If you use Weakest Precondition techniques for deriving the loop from the post-condition, the loop condition will be the simple matching condition as shown above.. The i < 100 is a bad idea because your loop could have an incorrect body that incremented the variable badly and still "appeared" to work..


3:


I would only use.
while (x != 100) 
if I wanted the loop to terminate when x was exactly 100.

So in the vast majority of cases I would use.
while (x < 100) 
which is a lot more common for counter controlled loops.. EDIT: On second thought, I would always use for-syntax in a counter-controlled loop, so that example should be.
for(int i=0; i < 100; ++i) 


4:


Using < is more common in Java.

Modern C++ uses !=.. != is more likely to catch errors in your code.

In most circumstances this is a good thing.

If for some reason the counter has not only reached but gone past the bound (usually on the first iteration), then the body will execute with an illegal value.

So long as the body of the loop is not hiding errors, then you'll get an exception.

If the body is hiding errors, the loop will execute billions of times and it should be obvious there is a bug.. As an example, an interesting vulnerability was found in the implementation of Adobe Flash last year.

A pointer used as array could be caused to be initialised as null.

Usually not a problem - the process safely crashes out whenever it is first dereferenced.

However, a loop with < was used, allowing the body to never executed which then allows the execution to continue.

After that, memory could be written at an attacker specified location.

Because the value of null is always 0, the attacker knows exactly which memory locations are being written to.

This would not have happened if the loop has used !=..


5:


The main advantage of use "!=" over "<" is that is something is going to fail, it should fail big.. For example, if a bug somewhere caused x to enter the loop set to 110, then x < 100 will never enter the loop --- a fact you might miss in debugging.

OTOH, if you use x!=100, it will never exit the loop -- something which could not be missing in debugging..


6:


I don't think < necessarily offers you more protection than !=.

If you have a case where i is being incremented in way that is unanticipated by you, you should be throwing an exception, not sweeping it under the rug with a <.. For example, if you're really worried about your while loops messing up, you could do something like this:.
x = 0; while (x != 100)  {    assert x >= 0;    assert x < 100;     y = 0;    while (y != 100)     {          assert y >= 0;      assert y < 100;       ... 

y++; } x++; }
That way, the moment your loop goes out of bounds, your program dies right away (crash early, crash often) and you know your code is messed up..


7:


I suspect this may have something to do with C++ iterators.. If you're using integers or pointers, < has a clearly defined meaning.

If you're using C++ iterators in a loop, < may not be defined, or may be hard to calculate.. For example, in running through a list, the C++ way would be:.
for(std::list<foo>::const_iterator i = bar.begin(); i != bar.end(); ++i) 
and really the only way to see if i is before bar.end() is to increment i indefinitely and see if it's ever equal to bar.end().. There's a considerable amount of value in doing minor things the same way all the time..


8:


I believe they are semantically the same, the only difference being with != numbers above 100 would obviously also meet the condition where as the < will prevent any number larger than 100 from making it through.. However in the case given, both operators will result in the same output.

Now, if somehow the x and y variables were being acted on outside that code, the "<" would be a better way to make sure there was a cutoff at 100 even if they entered with a value of 90, and were not able to continue at all if they entered with a value of 4000.

Obviously, the intent on what you are doing at the time would dictate which operator you chose, there are usually several methods to achieve the same result and not always one "correct" way..


9:


Yes.

They are semantically the same.

. The second syntax using the "<" operator is the one people in general use in this case and seems more intuitive (as the value of the variable is being incremented in the loop)..


10:


It's better to use the less than < in the loop.

There is a possibility that an error in the code will cause the counter to increment twice.

This means that the loop will suddenly become an infinite loop ( or until you blow MAXINT )..



82 out of 100 based on 52 user ratings 1102 reviews

*