views:

388

answers:

6

Hello everyone,

First of all, before I begin, I am using VC++ 2008 professional, running an Intel core2 on windows OS. I also know that this code will NEVER be executed on anything other than a core2/corei7 running Windows.

I have a while loop with 2 conditions that looks something like this: note: this is a much simplified version.

while((a != b) && (array[a] < c))

If the first condition (a != b) generates a false, will the second condition even be evaluated? or will the loop just terminate right there?

I did a few tests and it seems that it is indeed true.

However, here is the catch. When and if first condition evaluates false, the second condition WILL generate an access violation if it is evaluated. However, from what i can see, once the first condition is evaluated as false, the program doesn't bother to evaluate the second condition and quits the loop, thus saving me.

The problem is that I can't quite get rid of the access violation problem without making my very nice and neat code suddenly blow up on me. However, due to the little "bug" (i know it's a compiler optimization, not a bug), I seem to be able to get away from it. I also know this is probably not good programming practice to do, but to be honest, in my situation, if it works, I'm already ahead of the game.

My question is, will this "bug" or programming malpractice come back and bite me some day? Even when considering that I tested the hell out of this section and WILL ONLY EVER USE IT THIS ONE TIME?

+16  A: 

The second condition will not be evaluated unless the first one has been evaluated to true. You can count on this. Millions lines of code work because this is how C and C++ do short-curcuit logical expressions evaluation.

You can use it and count on it. If the first expression evaluates to false the second will not even start evaluating.

sharptooth
But is this ok to use even though the second condition will potentially cause the program to crash if ever evaluated in the state that causes the first condition to return false?
Faken
Yes, any standard-conforming C++ implementation will guarantee this.
sharptooth
@Faken - Yes, it is OK. Don't worry!
George Phillips
Alright, thank you very much for putting my fears to rest.
Faken
If it helps, Faken, look at it this way: the C++ standard forbids any implementation from evaluating the RHS if the LHS is false. So it isn't just that the compiler "doesn't" evaluate it. In RFC terminology, it MUST NOT evaluate it.
Steve Jessop
This is truly a case where it's not a bug, it's a feature!
Ari
danio
+2  A: 

It won't be evaluated. However, if you are worried -at all- that a routine you code will come back to bite you you should re-evaluate what you are writing. You have admitted that it is poor programming practice. You already know its going to be a problem. When those conditions are met, just fix the thing. You'll hate yourself less in the morning.

wlashell
I understand, but my little nice and neat 13 lines of code i have written depend on this to work properly...i have a lot to lose A LOT interms speed and efficiency if i fix it. When i mean A LOT i mean code execution will be on the order of 2-3 times slower.
Faken
Just don't worry. We write code depending on short-curcuit evaluation too. You don't expect the while loop to start if the loop condition is false at the beginning, do you? The same goes here.
sharptooth
I am interested, why do you agree that it's a poor programming practice?
Charles Bailey
+4  A: 

This is not a bug. C++ uses short-circuit evaluation, so the second condition will never be evaluated when the first condition is false.

Brandon E Taylor
A: 

The language guarantees this short circuiting behaviour so you should not be concerned at all by using it. It also works with || - if the first condition is true, the second is not evaluated.

markh44
+1  A: 

Relying on short the short-circuiting behaviour of the C++ logical AND and OR operators should not be considered a bad practice. It is perfectly idiomatic and often leads to clearer and more concise code.

E.g.

std::auto_ptr< SomeObject > data;

With short-circuiting &&:

// Clear expired data, if present
if( data.get() && data->expired )
    data.reset();

Without using the short-circuiting of && you need an extra level of if which leads to more verbose code.

// Clear expired data, if present
if( data.get() )
{
    if ( data->expired )
        data.reset();
}
Charles Bailey
A: 

The second condition will not be evaluated when the first condition is not true. As you said, this optimization is followed by all the C++ compilers.

If you still can't go with it, add a simple if statement in the while.

while ( a != b ) {
    if ( array[a] < c )
    {
         // your code goes here.
    }
    else
    {
        break;
    }
}
Narendra N