]> Cypherpunks.ru repositories - gostls13.git/commitdiff
spec: specify evaluation order for binary logical operations
authorMatthew Dempsky <mdempsky@google.com>
Fri, 25 Aug 2023 23:24:54 +0000 (16:24 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 14 Sep 2023 05:14:44 +0000 (05:14 +0000)
This CL clarifies the order of evaluation of the binary logical
operators, && and ||. The clarified semantics matches what cmd/compile
and x/tools/go/ssa already implement, and prohibit some optimizations
that are arguably allowed today but risk surprising users.

First, it specifies that the left operand is evaluated before the
right operand. This prohibits "(f() || true) && *p" from evaluating
"*p" before "f()".

Second, it specifies that binary logical operations are also ordered
lexically left-to-right with regard to function calls and receive
operations. This prohibits "h(*p || true || f(), g())" from evaluating
"*p" after "g()".

Finally, the "order of evaluation of [...] is not specified" wording
in the example is clarified to acknowledge that there are still some
other orderings that are implied lexically; e.g., x must be evaluated
and indexed before g(), and z now must be evaluated before h(). (Note:
Whether z is evaluated before or after f() remains unspecified, as
there's no lexical dependency.)

Change-Id: I9d316a7f1fbc83be663e116380a2cc7a4ace623d
Reviewed-on: https://go-review.googlesource.com/c/go/+/522938
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

doc/go_spec.html

index 0806fd738b0d0132d2d0d73dc7a64bdb32d41afb..09e2b6c97c5eeb69593802494ad4f8612892a252 100644 (file)
@@ -1,6 +1,6 @@
 <!--{
        "Title": "The Go Programming Language Specification",
-       "Subtitle": "Version of Aug 21, 2023",
+       "Subtitle": "Version of Sep 13, 2023",
        "Path": "/ref/spec"
 }-->
 
@@ -5208,7 +5208,7 @@ Specifically:
 <p>
 Logical operators apply to <a href="#Boolean_types">boolean</a> values
 and yield a result of the same type as the operands.
-The right operand is evaluated conditionally.
+The left operand is evaluated, and then the right if the condition requires it.
 </p>
 
 <pre class="grammar">
@@ -5786,24 +5786,28 @@ determine the evaluation order of individual initialization expressions in
 Otherwise, when evaluating the <a href="#Operands">operands</a> of an
 expression, assignment, or
 <a href="#Return_statements">return statement</a>,
-all function calls, method calls, and
-communication operations are evaluated in lexical left-to-right
-order.
+all function calls, method calls,
+<a href="#Receive operator">receive operations</a>,
+and <a href="#Logical_operators">binary logical operations</a>
+are evaluated in lexical left-to-right order.
 </p>
 
 <p>
 For example, in the (function-local) assignment
 </p>
 <pre>
-y[f()], ok = g(h(), i()+x[j()], &lt;-c), k()
+y[f()], ok = g(z || h(), i()+x[j()], &lt;-c), k()
 </pre>
 <p>
 the function calls and communication happen in the order
-<code>f()</code>, <code>h()</code>, <code>i()</code>, <code>j()</code>,
+<code>f()</code>, <code>h()</code> (if <code>z</code>
+evaluates to false), <code>i()</code>, <code>j()</code>,
 <code>&lt;-c</code>, <code>g()</code>, and <code>k()</code>.
 However, the order of those events compared to the evaluation
 and indexing of <code>x</code> and the evaluation
-of <code>y</code> is not specified.
+of <code>y</code> and <code>z</code> is not specified,
+except as required lexically. For instance, <code>g</code>
+cannot be called before its arguments are evaluated.
 </p>
 
 <pre>