5

Given a simple expression like

*a[0]

where a is declared as *[]string (a pointer to a slice of strings).

Where does the standard exactly explain the order in which the language constructs are evaluated?

I've found that none of them is actually an operator, and the only couple of mentions of the precedence keyword mentioned in the spec:

  1. https://golang.org/ref/spec#Notation
  2. https://golang.org/ref/spec#Operators

So, what part of the spec would explain the order of evaluation of the provided expression?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
zerkms
  • 249,484
  • 69
  • 436
  • 539

1 Answers1

5

The definitive section is Primary Expressions:

Primary expressions are the operands for unary and binary expressions.

It goes on to define primary expressions, but basically, this includes slice expressions, meaning that the slice expression a[0] is the operand for the unary operator *. A special case was made for pointers to arrays (see below).

According to Address Operators:

For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal. If the evaluation of x would cause a run-time panic, then the evaluation of &x does too.

For an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x. If x is nil, an attempt to evaluate *x will cause a run-time panic.

This implies, but does not explicitly state, that a slice indexing expression or field selector expression to the right of the pointer indirection operator is evaluated as a whole before the indirection is evaluated.

Also, pointer indirection (*x) is an operator, specifically, an Address Operator. The slice index reference is not an operator but rather an Index Expression.

Also note that:

For a of pointer to array type:

a[x] is shorthand for (*a)[x]

Though the same cannot be said of pointers to slice types.

Community
  • 1
  • 1
Adrian
  • 42,911
  • 6
  • 107
  • 99
  • 1
    The relevant grammar here is for the [Unary Expression](https://golang.org/ref/spec#UnaryExpr) -- unary operators apply to the expression to their right, not to the first identifier. – JimB Jul 19 '17 at 20:48
  • https://play.golang.org/p/HDw5eP6BMC - how is it a "shorthand" if they evaluate differently? – zerkms Jul 19 '17 at 20:49
  • 1
    As the spec says, it works for arrays: https://play.golang.org/p/y898H_klZq though it's strange that it does not work for pointers to slices. – Adrian Jul 19 '17 at 20:51
  • Sorry, but I still cannot understand how `Order of Evaluation` declares that in `*a[0]` the index expression is done first. – zerkms Jul 19 '17 at 20:53
  • "Unary operators have the highest precedence". --- if they do, why it's not evaluated first? With slices `*a[0]` is evaluated as `*(a[0])` – zerkms Jul 19 '17 at 20:55
  • @zerkms you got a spec ref that explains it more accurately? – Adrian Jul 19 '17 at 20:55
  • @Adrian that's why I asked my question: I don't see anything in the spec that explains it. So either I cannot search or the spec misses it. At the moment your answer quotes "Unary operators have the highest precedence" while the observed behaviour is actually the opposite (and I'm not even sure how the "precedence" can be applied at all, when one is an operator `*`, and the other `[]` is not). – zerkms Jul 19 '17 at 20:56
  • 1
    OK, that's the best I can come up with. The spec is really not clear on this and provides bits and pieces in a lot of different sections. – Adrian Jul 19 '17 at 21:00
  • @Adrian yep, the latest quote with the implication makes me happy enough, thanks :-) – zerkms Jul 19 '17 at 21:01
  • 1
    We should post to the go mailing list and complain ;) – Adrian Jul 19 '17 at 21:02
  • Well, not complain, but address it so that the language designers could improve it, if they see it as a problem :-) If you do please update your answer with a link so that I could subscribe. – zerkms Jul 19 '17 at 21:02
  • 1
    Reason for the deviation between slices and arrays can be found in this answer: [Slicing a slice pointer passed as argument](https://stackoverflow.com/questions/38013922/slicing-a-slice-pointer-passed-as-argument/38014097#38014097). – icza Jul 19 '17 at 21:25