From 856cf23a8acfa14756a6e9b82ace76f5604262c9 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Fri, 25 Aug 2023 16:24:54 -0700 Subject: [PATCH] spec: specify evaluation order for binary logical operations 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 Reviewed-by: Ian Lance Taylor LUCI-TryBot-Result: Go LUCI --- doc/go_spec.html | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index 0806fd738b..09e2b6c97c 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -5208,7 +5208,7 @@ Specifically:

Logical operators apply to boolean 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.

@@ -5786,24 +5786,28 @@ determine the evaluation order of individual initialization expressions in
 Otherwise, when evaluating the operands of an
 expression, assignment, or
 return statement,
-all function calls, method calls, and
-communication operations are evaluated in lexical left-to-right
-order.
+all function calls, method calls,
+receive operations,
+and binary logical operations
+are evaluated in lexical left-to-right order.
 

For example, in the (function-local) assignment

-y[f()], ok = g(h(), i()+x[j()], <-c), k()
+y[f()], ok = g(z || h(), i()+x[j()], <-c), k()
 

the function calls and communication happen in the order -f(), h(), i(), j(), +f(), h() (if z +evaluates to false), i(), j(), <-c, g(), and k(). However, the order of those events compared to the evaluation and indexing of x and the evaluation -of y is not specified. +of y and z is not specified, +except as required lexically. For instance, g +cannot be called before its arguments are evaluated.

-- 
2.44.0