Question

In the PHP code

if(a() && b())

when the first operand evaluates to false, b() will not be evaluated.

Similarly, in

if (a() || b())

when the first operand evaluates to 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';
}
?>
Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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

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.

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.

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 ^^ )

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.

In Delphi it's a compiler option.

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

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.

In standard FORTRAN or Fortran, the operands of a boolean expression can be evaluated in any order. Incomplete evaluation is permitted, but implementation defined.

This allows optimisation of boolean expressions that would not be permitted if strict Left-To-Right ordering was enforced. Expressions which require strict ordering must be decomposed into seperate conditionals, or implementation-dependent assumptions can be made.

Since decomposition is used to enforce ordering, it follows that seperate IF statements can not always be optimised into a single expression. However, short-circuit evaluation is explicit with decomposition, and this is never worse than languages which enforce strict left-to-right ordering to allow lazy evaluation.

Languages wich are derived from FORTRAN (Fortran, BASIC, VBn), and languages which were designed to achieve FORTRAN-like efficiency (Pascal, Ada) initially followed the FORTRAN example of allowing out-of-order evaluation.

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. (Original)

All BITWISE operators such as & and |, are processed. (Edit: 5/10/17)

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.

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>

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.

Other answers have given good examples of languages with and without short circuit evaluation so I won't repeat them.

Just one interesting point to add: Lisps such as Clojure have boolean short circuit evaluation, but in addition you can quite trivially define any operator you like with short circuit evaluation through the use of macros.

Example of a short-circuiting "nand" operation in Clojure:

(defmacro nand 
  ([x] 
    `(not ~x))
  ([x & xs] 
    `(let [nand# (not ~x)]
       (if nand# 
         true               ; short circuit if we can prove the nand is true
         (nand ~@xs)))))    ; continue with the other expressions otherwise

(nand true true)
=> false

(nand false (println "Expression with a side effect!"))
=> true
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top