Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

Short-circuit evaluation

From Wikipedia, the free encyclopedia
Programming language construct
Not to be confused withShort-circuit test.
icon
This articleneeds additional citations forverification. Please helpimprove this article byadding citations to reliable sources. Unsourced material may be challenged and removed.
Find sources: "Short-circuit evaluation" – news ·newspapers ·books ·scholar ·JSTOR
(August 2013) (Learn how and when to remove this message)
Evaluation strategies

Short-circuit evaluation,minimal evaluation, orMcCarthy evaluation (afterJohn McCarthy) is the semantics of someBoolean operators in someprogramming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of theAND function evaluates tofalse, the overall value must befalse; and when the first argument of theOR function evaluates totrue, the overall value must betrue.

In programming languages withlazy evaluation (Lisp,Perl,Haskell), the usualBoolean operators short-circuit. In others (Ada,Java,Delphi), both short-circuit and standard Boolean operators are available. For some Boolean operations, likeexclusive or (XOR), it is impossible to short-circuit, because both operands are always needed to determine a result.

Short-circuit operators are, in effect,control structures rather than simple arithmetic operators, as they are notstrict. Inimperative language terms (notablyC andC++), where side effects are important, short-circuit operators introduce asequence point: they completely evaluate the first argument, including anyside effects, before (optionally) processing the second argument.ALGOL 68 usedproceduring to achieveuser-defined short-circuit operators and procedures.

The use of short-circuit operators has been criticized as problematic:

The conditional connectives — "cand" and "cor" for short — are ... less innocent than they might seem at first sight. For instance,cor does not distribute overcand: compare

(Acand B)cor Cwith (Acor C)cand (Bcor C);

in the case ¬A ∧ C , the second expression requires B to be defined, the first one does not. Because the conditional connectives thus complicate the formal reasoning about programs, they are better avoided.

— Edsger W. Dijkstra[1]

Definition

[edit]

In any programming language that implements short-circuit evaluation, the expressionx andy is equivalent to theconditional expressionifx theny elsex, and the expressionx ory is equivalent toifx thenx elsey. In either case,x is only evaluated once.

The generalized definition above accommodates loosely typed languages that have more than the twotruth-valuesTrue andFalse, where short-circuit operators may return the last evaluated subexpression. This is called "last value" in the table below. For a strictly-typed language, the expression is simplified toifx theny elsefalse andifx thentrue elsey respectively for the Boolean case.

Precedence

[edit]

AlthoughAND takesprecedence overOR in many languages, this is not a universal property of short-circuit evaluation. An example of the two operators taking the same precedence and beingleft-associative with each other isPOSIX shell's command-list syntax.[2]: §2.9.3 

The following simple left-to-right evaluator enforces a precedence ofAND overOR by acontinue:

function short-circuit-eval (operators,values)letresult := Truefor each (op,val) in (operators,values):ifop = "AND" &&result = Falsecontinueelse ifop = "OR" &&result = Truereturnresultelseresult :=valreturnresult

Formalization

[edit]

Short-circuit logic, with or without side-effects, have been formalized based onHoare's conditional. A result is that non-short-circuiting operators can be defined out of short-circuit logic to have the same sequence of evaluation.[3]

Comparison with bitwise operators

[edit]

& and| arebitwise operators that occur in many programming languages. The major difference is that bitwise operations operate on the individual bits of a binary numeral, whereas conditional operators operate on logical operations. Additionally, expressions either side of a bitwise operator are always evaluated. In some languages, includingJava andC#, they can be used on Boolean operands to force both sides to be evaluated.

if(expression1||expression2||expression3)

If expression 1 is true, expressions 2 and 3 are not checked.

if(expression1|expression2|expression3)

This checks expressions 2 and 3, even if expression 1 is true.

Short-circuit operators can thus reduce run times by avoiding unnecessary calculations. They can also avoid null exceptions when expression 1 checks whether an object is valid.

Support in common programming and scripting languages

[edit]

The following table is restricted to common programming languages and the basic Boolean operators forlogical conjunctionAND andlogical disjunctionOR.Bitwise operators are shown only for languages that allow them to be used as eager Boolean operators and have the same return type.

Note that there are more short-circuit operators, for example theternary conditional operator, which iscond? e1: e2 (C,C++,Java,PHP),if condthen e1else e2 (ALGOL,Haskell,Kotlin,Rust),e1if condelse e2 (Python). Please take a look atternary conditional operator#Usage.

Boolean operators in common languages
LanguageEager operatorsShort-circuit operatorsResult type
Adaand,orand then,or elseBoolean
ALGOL 68and, &, ∧ ; or, ∨andf , orf(both user defined)Boolean
APL,:AndIf,:OrIfBoolean
awknone&&,||Boolean
C,Objective-C&,|[a]&&,||[5]int
C++[b]none&&,||[6]Boolean
C#&,|&&,||Boolean
D[c]&,|&&,||Boolean
Eiffeland,orand then,or elseBoolean
Erlangand,orandalso,orelseBoolean
Fortran[d].and.,.or..and.,.or.Boolean
Go,Haskell,OCaml[e]none&&,||Boolean
Java,R,Swift&,|&&,||[f]Boolean
JavaScriptnone&&,||Last value
Julianone&&,||Last value
Kotlinand,or&&,||Boolean
Lisp,Lua[e],Schemenoneand,orLast value
MATLAB[g]&,|&,|,&&,||Boolean
MUMPS (M)&,!noneNumeric
Modula-2noneAND,ORBoolean
Pascaland,or[h][i]and_then,or_else[i]Boolean
Perl&,|&&,and,||,orLast value
PHPnone&&,and,||,orBoolean
POSIX shell,Bashnone&&,||Numeric (exit code)
PowerShell Scripting Languagenone-and,-orBoolean
Python&,|and,orLast value
Ruby&,|&&,and,||,or[9]Last value
Rust&,|&&,||[10]Boolean
Smalltalk&,|and:,or:[j]Boolean
Standard MLUnknownandalso,orelseBoolean
Visual Basic .NETAnd,OrAndAlso,OrElseBoolean
Visual Basic,Visual Basic for Applications (VBA)And,OrnoneNumeric
  1. ^The bitwise operators behave like Boolean operators when both arguments are of typebool or take only the values0 or1.[4]
  2. ^Whenoverloaded, the operators&& and|| are eager and can return any type.
  3. ^This only applies to runtime-evaluated expressions,static if andstatic assert. Expressions in static initializers or manifest constants use eager evaluation.
  4. ^Fortran operators are neither short-circuit nor eager: the language specification allows thecompiler to select the method for optimization.
  5. ^abIn lua and OCaml, bitwise operators&,| (OCamlland,lor) are restricted to integers and cannot be used with Booleans.
  6. ^In Java, these along with?…: are sometimes referred to as "conditional operators".[7]
  7. ^The operator& behaves like a short-circuit operator when used in a statement followingif orwhile.[8]
  8. ^ISO/IEC 10206:1990 Extended Pascal allows, but does not require, short-circuiting.
  9. ^abDelphi andFree Pascal default to short circuit evaluation. This may be changed bycompiler options but does not seem to be used widely.
  10. ^Smalltalk uses short-circuit semantics as long as the argument toand: is a block (e.g.,falseand: [Transcriptshow:'Wont see me']).

Common use

[edit]

Avoiding undesired side effects of the second argument

[edit]

Usual example, using aC-based language:

intdenom=0;if(denom!=0&&num/denom){...// ensures that calculating num/denom never results in divide-by-zero error}

Consider the following example:

inta=0;if(a!=0&&myfunc(b)){doSomething();}

In this example, short-circuit evaluation guarantees thatmyfunc(b) is never called. This is becausea != 0 evaluates tofalse. This feature permits two useful programming constructs.

  1. If the first sub-expression checks whether an expensive computation is needed and the check evaluates tofalse, one can eliminate expensive computation in the second argument.
  2. It permits a construct where the first expression guarantees a condition without which the second expression may cause arun-time error.

Both are illustrated in the following C snippet where minimal evaluation prevents both null pointer dereference and excess memory fetches:

boolisFirstCharValidAlphaUnsafe(constchar*p){returnisalpha(p[0]);// SEGFAULT highly possible with p == NULL}boolisFirstCharValidAlpha(constchar*p){returnp!=NULL&&isalpha(p[0]);// 1) no unneeded isalpha() execution with p == NULL, 2) no SEGFAULT risk}

Idiomatic conditional construct

[edit]

Since minimal evaluation is part of an operator's semantic definition and not an optionaloptimization, a number of coding idioms rely on it as a succinct conditional construct. Examples include:

Perl idioms:

some_conditionordie;# Abort execution if some_condition is falsesome_conditionanddie;# Abort execution if some_condition is true

POSIX shell idioms:[11]

modprobe-qsome_module&&echo"some_module installed"||echo"some_module not installed"

This idiom presumes thatecho cannot fail.

Possible problems

[edit]

Untested second condition leads to unperformed side effect

[edit]

Despite these benefits, minimal evaluation may cause problems for programmers who do not realize (or forget) it is happening. For example, in the code

if(expressionA&&myFunc(b)){doSomething();}

ifmyFunc(b) is supposed to perform some required operation regardless of whetherdoSomething() is executed, such as allocating system resources, andexpressionA evaluates as false, thenmyFunc(b) will not execute, which could cause problems. Some programming languages, such asJava, have two operators, one that employs minimal evaluation and one that does not, to avoid this problem.

Problems with unperformed side effect statements can be easily solved with proper programming style, i.e., not using side effects in Boolean statements, as using values with side effects in evaluations tends to generally make the code opaque and error-prone.[12]

Reduced efficiency due to constraining optimizations

[edit]

Short-circuiting can lead to errors inbranch prediction on moderncentral processing units (CPUs), and dramatically reduce performance. A notable example is highly optimized ray with axis aligned box intersection code inray tracing.[clarification needed] Some compilers can detect such cases and emit faster code, but programming language semantics may constrain such optimizations.[citation needed]

An example of a compiler unable to optimize for such a case isJava'sHotspot virtual machine (VM) as of 2012.[13]

See also

[edit]

References

[edit]
  1. ^Edsger W. Dijkstra "On a somewhat disappointing correspondence", EWD1009-0, 25 May 1987full text
  2. ^"Shell Command Language".pubs.opengroup.org.
  3. ^Bergstra, Jan A.; Ponse, A.; Staudt, D.J.C. (2010). "Short-circuit logic".arXiv:1010.3674 [cs.LO].
  4. ^ISO/IEC 9899 standard, sections 6.2.5, 6.3.1.2, 6.5 and 7.16.
  5. ^ISO/IEC 9899 standard, section 6.5.13
  6. ^ISO/IEC IS 14882 draft.
  7. ^"Equality, Relational, and Conditional Operators (The Java™ Tutorials > Learning the Java Language > Language Basics)".docs.oracle.com. Retrieved2019-04-29.
  8. ^"and, &".MathWorks Help Center. Retrieved2025-02-02.
  9. ^"operators - Documentation for Ruby 3.3".docs.ruby-lang.org. Retrieved2024-04-02.
  10. ^"std::ops - Rust".doc.rust-lang.org. Retrieved2019-02-12.
  11. ^"What does || mean in bash?". stackexchange.com. Retrieved2019-01-09.
  12. ^"Referential Transparency, Definiteness and Unfoldability"(PDF). Itu.dk. Retrieved2013-08-24.
  13. ^Wasserman, Louis (11 July 2012)."Java: What are the cases in which it is better to use unconditional AND (& instead of &&)".Stack Overflow.
Retrieved from "https://en.wikipedia.org/w/index.php?title=Short-circuit_evaluation&oldid=1335953335"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2026 Movatter.jp