N/T
-
Manip wrote:If you wrote this program in C/C++ or Visual Basic or any of the .net langs you will find that you receive two 'Hello World' message boxes and no 'Woo!'
Erm. I am confused (and now a bit worried about short circuiting evaluations). I know for a fact that GCC optimises this and I can't believe that Microsoft's compiler wouldn't. Does this happen in debug and release?
-
What are you talking about? The standard for C++ requires the short circuit. And VC++ 2003 certainly behaves correctly. I'm certain C# is no different here (though I haven't tested). I won't venture to guess about VB, though I would be surprised if it were any different.
-
Oh, and short circuiting isn't really about optimizing. I doubt there is any language spec that would leave this as an optimization (IOW, leave it up to an implementation to decide how to behave here). Optimizations are optional implementation details that are not allowed to modify the significant behavior of the code. Short circuiting most certainly drastically modifies the significant behavior, and thus must be specified as always occurs or never occurs and compilers are unable to "optimize" the code beyond that.
-
I'd point out that the line of code
if ( myLogic() && myLogic() )
won't compile as C# because you can't apply && to two ints. If you change myLogic to return bool and then have it return false, the short circuit takes place with C#.
Edit: Quick google tells me VB.Net does not do short circuit .. but you can use new keywords AndAlso, OrElse in order to get the same effect. -
Rossj wrote:Edit: Quick google tells me VB.Net does not do short circuit .. but you can use new keywords AndAlso, OrElse in order to get the same effect.
Yep. Historically, VB's And and Or do not shortcircuit. For VB.Net 1.0 beta 1, they changed this, but it broke too much existing code so people complained. So now we're stuck with the ugly AndAlso and OrElse operators...
C, C++, C#, Java, they all shortcircuit. -
Manip wrote:If you wrote this program in C/C++ or Visual Basic or any of the .net langs you will find that you receive two 'Hello World' message boxes and no 'Woo!' message box.
This does not happen with VC++, VC#, but WILL happen with VB.NET (by design as someone else already said) -
Rossj wrote:I'd point out that the line of code
if ( myLogic() && myLogic() )
won't compile as C# because you can't apply && to two ints. If you change myLogic to return bool and then have it return false, the short circuit takes place with C#.
If memory serves me correctly, if(myLogic()) won't work in Java either... for the same reason, namely, if (...) requires a boolean.
This breaks things like
if (ptr)
but it's REALLY NICE for catching bugs like
if (i = 1) (instead of if (i == 1))
On the other hand if (!!ptr) looks kind of silly
-
Mom (thinks in VB-ish):
If kid.CleanTheDishes() And kid.DoHomework() Then
we.GoToMovie you.PickMovie()
End If
Child (thinks in C-ish)
if (me->CleanTheDishes() && me->DoHomework())
{ we->GoToMovie(me->PickMovie());
} else
{ me->fool_around();
}
boolean CleanTheDishes()
{ ...
if (kitchen->Inventory("soap") < dishes->SoapNeeded())
{ shoppingList->add("soap");
todo->add("Clean The Dishes");
return false;
}
...
}
Mom:
If Todo.Contains("Clean The Dishes") Then
Ask kid, "why didn't you clean the dishes"
End If
Child:
mom->show(kitchen->Inventory);
mom->show(shoppingList);
Mom:
If kid.Explanation.IsSatisfactory() Then
Pat kid
End If
If Not kid.Homework.IsDone Then
Ask kid, "why didn't you do your homework"
End If
Child:
if (mom->makes_no_sense())
{ mom->explain("Because && short-circuits");
mom->explain("See, doing homework is just a < i >side effect< /i >");
mom->explain("I already knew that !we->GoToMovie(...)");
}
Mom:
kid.GetSupper = False
kid.SendToRoom
Child:
while (me->in_room)
{ me->grumble("She just doesn't understand...");
}
-
ok, I have been jumping between languages too much lately..
Is C# the one that uses && for for short-circuit and & for non-shor-circuit? or Is that javascript?
Jorgie -
From the MSDN docs on C++:
Operator Description && The logical-AND operator produces the value 1 if both operands have nonzero values. If either operand is equal to 0, the result is 0. If the first operand of a logical-AND operation is equal to 0, the second operand is not evaluated. || The logical-OR operator performs an inclusive-OR operation on its operands. The result is 0 if both operands have 0 values. If either operand has a nonzero value, the result is 1. If the first operand of a logical-OR operation has a nonzero value, the second operand is not evaluated.
From C#:
The conditional-AND operator (&&) performs a logical-AND of its bool operands, but only evaluates its second operand if necessary.
The conditional-OR operator (||) performs a logical-OR of its bool operands, but only evaluates its second operand if necessary.
Binary & operators are predefined for the integral types and bool. For integral types, & computes the bitwise AND of its operands. For bool operands, & computes the logical AND of its operands; that is, the result is true if and only if both its operands are true.
(this means that yes, in C# && short-circuits while & doesn't (similar for |). In C(++) this is also the case, not by design but as a side-effect of the way integers are coerced to boolean values)
For completeness
From VB.NET:
The operators AndAlso and OrElse are only defined on the type Boolean and short-circuit; that is, in certain situations, the second operand will not be evaluated at run time. -
"Binary & operators are predefined for the integral types and bool. For integral types, & computes the bitwise AND of its operands. For bool operands, & computes the logical AND of its operands; that is, the result is true if and only if both its operands are true.
(this means that yes, in C# && short-circuits while & doesn't (similar for |). In C(++) this is also the case, not by design but as a side-effect of the way integers are coerced to boolean values)"
Thank you! That is what I thought!
Jorgie
-
But don't get in the habit of using & this way - you might get surprising results.
For example,
(bool)((int) 10 & (int) 5) != (bool) 10 & (bool) 5
The LHS is false, the RHS is true.
-
&& is logical and-ing
& is bitwise and-ing
true && true == true
true && false == false
false && true == false
false && false == false
12 & 5 == 1100b & 0101b == 0100b == 4
Not especially fast or useful, except for unsetting bits in a bit field
EDIT: duh 1100b is 12 not 10
-
I have always been under the impression that when evaluating:
if(x && y)
it is undefined whether y will be evaluated in the case that x is false. Because of this, it is a good idea to simply not do this.
It never ceases to amaze me how often people will code a complicated algorithm in a few lines. The compiler/jit will break it apart and optimize it, so why not make it readable and obvious?
(BTW, I used to write in x86 ASM, so I understand that there was a day when short and sweet was better...that day was 15+ years ago).
-
ScanIAm wrote:
I have always been under the impression that when evaluating:
if(x && y)
it is undefined whether y will be evaluated in the case that x is false.
That is not true. From the ISO C++ standard:
5.14 Logical AND operator
logical-and-expression:
inclusive-or-expression
logical-and-expression && inclusive-or-expression
1 The && operator groups left-to-right. The operands are both implicitly converted to type bool (clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
And from the ECMA C# standard:
14.11 Conditional logical operators
The && and || operators are called the conditional logical operators. They are also called the "shortcircuiting" logical operators.
conditional-and-expression:
inclusive-or-expression
conditional-and-expression && inclusive-or-expression
conditional-or-expression:
conditional-and-expression
conditional-or-expression || conditional-and-expression
The && and || operators are conditional versions of the & and | operators:
• The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is true.
• The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is
false. -
IIRC the standard for C++ got changed at some point. Possibly between VC++ 5.0 and 6.0? Early on on one of the projects I worked on we had a terrible time with people putting function calls on the right hand side of a && that depended on the left hand side. Since none of us knew for sure what the standard was we couldn't rule it out as a reason why we had things crashing some times. (Sure we had plenty of other reasons why the system crashed but why have something else to worry about right?)
Now that things are definitively standardized it seems like good coding practice to break those things apart and nest them properly. The added readability and explicit dependence described is worth it. Saving an extra 2 lines of code seems like being lazy. -
JKelley wrote:IIRC the standard for C++ got changed at some point. Possibly between VC++ 5.0 and 6.0?
Actually, the official first edition of the C++ standard was finalised in 1998, after Visual C++ 6 was released.
The text I quoted comes from the second edition, which was accepted as a standard in 2003.
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.