views:

1545

answers:

16

In the PHP code

if(a() && b())

when the first argument is false, b() will not be evaluated.

Similarly, in

if (a() || b())

when the first argument is true, b() will not be evaluated..

Is this true for all languages, like Java, C#, etc?

This is the test code we used.

<?php
function a(){
echo 'a';
return false;
}

function b(){
echo 'b';
return true;
}


if(a() && b()){
echo 'c';
}
?>
+19  A: 

It's not true for VB6.

In VB.net you have to use "AndAlso" instead of "And" if you want it to skip evaluating the second expression.

Alex Warren
Likewise, the shortcircuiting `Or` is `OrElse`. Which I like. It's VB's "Do it my way, OrElse!"
Greg D
A: 

You might find it helpful to refer to the language specifications.

It has been true of all the languages in the C lineage that I have used. Neliac, C, C++, Java.

This article discusses the idea

djna
+43  A: 

This is called short-circuit evaluation.

It is generally true for languages derived from C (C, C++, Java, C#) but not true for all languages.

For example, VB6 does not do this, nor was it done in early versions of VB.NET. VB8 (in Visual studio 2005) introduced the AndAlso and OrElse operators for this purpose.

Also, from comments, it seems that csh performs short-circuit evaluation from right to left, to make matters even more confusing.

It should also be pointed out that short-circuit evaluation (or lack of) has its dangers to be aware of. For example, if the second operand is a function that has any side effects, then the code may not perform exactly as the programmer intended.

Patrick McDonald
Don't forget the VB.NET OrElse operator, too!
R. Bemrose
Fair point, thanks :)
Patrick McDonald
Are there any languages that evaluate from right to left, I wonder?
Dan Diplo
@Dan Diplo: One of the unix shells does that for some arithmetical operations. There is a SO question on the matter...
dmckee
Dan - C/C++ compilers are free to reorder the arguments in the if statement, so you can't be sure only a() would be called - it might be only b()
Martin Beckett
It is csh. Here we go: http://stackoverflow.com/questions/1010049/in-csh-why-does-4-3-1-0
dmckee
In Delphi this is optional, default on.
Gamecat
+12  A: 

It's called short-circuit evaluation and most languages do this. In some languages there exists operators that don't do this.

waxwing
+5  A: 

It is true for languages that are "children" of the C : PHP, Java, C++, C#, ... or in the same "inspiration", like Perl.

But it is not true for VB (at least before .NET, which introduced new keywords for that).
(And that's really disturbing the first you work with VB ^^ )

Pascal MARTIN
It is also disturbing when you are going from C# to VB.NET. This is especially annoying when using stuff like: If(myVar ISNOT Nothing And myVar.Count > 0). The AND needs to be an ANDALSO. Most cases you won't encounter issues, but when myVar is nothing/null you might get confused. I needed to use .NET Reflector to find out that I needed to use AndAlso (google for "VB.NET And" did not give the wanted results).
Gertjan
+7  A: 

The original version of Pascal did not, which caused lots of grief. Modern Pascals, such as Delphi work the same way as C et al.

anon
+4  A: 

This is true for Java as well but the operators |, & etc will evaluate both sides.

willcodejavaforfood
Imagist
Joachim Sauer
+17  A: 

Is this true for ALL languages, like JAVA, C#, etc?

In C# this is only true for the short-circuiting operators '||' and '&&'; if you just use '|' or '&' it will evaluate both sides every time.

Marc Gravell
Java has the same non-short-circuited operators.
R. Bemrose
David Thornley
+1  A: 

This is called short-circuit evaluation and it is common for all of the languages that I have ever worked in (C, C++, C#, Java, Smalltalk, Javascript, Lisp) except for VB, VB.NET and Fortran.

It's actually a pretty useful feature. Without short-circuiting you wouldn't be able to do this:

if (a != null && a.isBlank())

Without short-circuiting you would have to have nested if statements because the second part would throw an error if a was null.

Jeff Hornby
Not lisp. Well, not unless `or` is defined as a macro.
troelskn
Really? I did Lisp over 20 years ago in university so you'll have to excuse my memory.
Jeff Hornby
OR is a macro in Common Lisp, I believe. I don't think it's a special form (like IF), and it certainly does short-circuit. I don't know if there are any Lisp versions that don't short-circuit, but I haven't seen one.
David Thornley
+3  A: 

Ada has special short-circuited forms of conditionals:

and then
or else

used like this:

if p.next /= null and then p.next.name = 'foo'
if x = 0 or else 1/x = y

In some ways it's kind of nice because you can deduce that the programmer knew the expression needed to be short-circuited and that the conditional is not working by accident.

Mark Harrison
+1  A: 

Coldfusion will natively do short-circut evaluation. I am sure all CF developers have written:

<cfif isdefined("somevariable") and somevariable eq something>
//do logic
</cfif>
andrewWinn
+2  A: 

Most languages (all that I've seen) use short circuit evaluation on CONDITIONAL operators such as && and ||. They will stop evaluating as soon as one of the conditions has satisfied the requirement. (The first false on &&. The first true on ||)

All BINARY operators such as & and |, are processed.

Brad Bruce
This might explain why VB operates differently, as it does not make a distinction between bitwise and logical operators.
Patrick McDonald
Pavel Minaev
+3  A: 

In Delphi it's a compiler option.

Julian de Wit
Oh dear god. So you can have completely unpredictable bugs based on what option someone else passes the compiler when they built your code?
Alex Feinman
This tends to be true of all compilers which must deal with languages that have changed over time, as Pascal and C have. In practice, no-one ever uses this particular Delphi option.
anon
Yes, it seemed pretty risky to mee too so I never touched it.. :S
Julian de Wit
+3  A: 

Microsoft VBScript (often used in conjunction with 'Classic' ASP) had no short-circuit evaluation for boolean operators, instead it uses bitwise evaluation. Which is one of the many reasons it is possibly the worst language ever!

"What's going on is that VBScript is not logical. VBScript is bitwise. All the so-called logical operators work on numbers, not on Boolean values! Not, And, Or, XOr, Eqv and Imp all convert their arguments to four-byte integers, do the logical operation on each pair of bits in the integers, and return the result. If True is -1 and False is 0 then everything works out, because -1 has all its bits turned on and 0 has all its bits turned off. But if other numbers get in there, all bets are off".

Taken from this blog. by Eric Lippert.

Dan Diplo
+1  A: 

In Erlang, the and and or operators do not do short-circuit evaluation; you have to use orelse and andalso operators if you want short-circuiting behavior.

mipadi
Ick. I bet that causes a lot of bugs.
David Thornley
It was kind of a "gotcha" until I got used to it. Code like `A > 1 and math:sqrt(A)` can cause problems if you don't realize the behavior.
mipadi
+1  A: 

MATLAB is one language that distinguishes between "standard" logical operators and short-circuit operators:

  • & (AND operator) and | (OR operator) can operate on arrays in an element-wise fashion.
  • && and || are short-circuit versions for which the second operand is evaluated only when the result is not fully determined by the first operand. These can only operate on scalars, not arrays.
gnovice