Pointer dereference operator precedence

339 views
Skip to first unread message

adrian...@gmail.com

unread,
Jul 19, 2017, 6:28:47 PM7/19/17
to golang-nuts
A question on Stack Overflow led me to carefully examine the spec and I feel like there may be some detail that's missing - the behavior is easy enough to work with, but it's effectively undefined according to the language spec. Specifically, with a variable x of type *[]string for example, *x[0] will not work because it is evaluated as *(x[0]), not as (*x)[0]. This is unexpected based on the spec because the only specifications that could apply are the general order of evaluation, which is left to right (not the case here), and operator precedence which states that pointer dereference is a unary operator and unary operators have highest precedence (again clearly not what's happening).

The closest it comes to explaining this behavior is in the section on address operators, which implies that the address operator & applies to the entire slice expression next to it (or struct field selector, etc). This leaves one to assume the same implication applies to the pointer dereference operator as well.

Is there something covering this that I glossed over reading the spec? If it's not just something I missed, is this worth clarifying in the spec, without changing the behavior (purely a documentation change)?

Jan Mercl

unread,
Jul 19, 2017, 6:44:32 PM7/19/17
to golang-nuts


Consider

var x *[N]*T

What is the type of *x[0]? *T or T? Only the parentheses can disambiguate it: (*x)[0] vs *(x[0]).

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

-j

--

-j

adrian...@gmail.com

unread,
Jul 19, 2017, 6:53:52 PM7/19/17
to golang-nuts
That's fine, though my example was for a pointer to a slice of a non-pointer type. Regardless of the type of the slice elements, it evaluates the slice expression first, then the pointer dereference on the result of the expression.

It's not the behavior that concerns me though, it's that it's undocumented. The spec should say what happens. The only way to know right now (as far as I can tell) is to try it and figure it out from the compiler errors. I'd think expressed behavior shouldn't be the only documentation for a language aspect.

Ian Lance Taylor

unread,
Jul 19, 2017, 6:59:29 PM7/19/17
to adrian...@gmail.com, golang-nuts
This is expressed in the EBNF grammar in the language spec. x[0] is a
PrimaryExpr. *x[0] is a unary_op applied to a PrimaryExpr.

Ian

adrian...@gmail.com

unread,
Jul 19, 2017, 7:10:20 PM7/19/17
to golang-nuts, adrian...@gmail.com
The EBNF specifies the syntax, not the behavior. EBNF does not indicate the order of evaluation of source code, only the order of characters in the source code.

Ian Lance Taylor

unread,
Jul 19, 2017, 9:08:25 PM7/19/17
to adrian...@gmail.com, golang-nuts
On Wed, Jul 19, 2017 at 4:10 PM, <adrian...@gmail.com> wrote:
>
> The EBNF specifies the syntax, not the behavior. EBNF does not indicate the
> order of evaluation of source code, only the order of characters in the
> source code.

Fair point. In this case it is also intended to indicate the
precedence. In fact, in every case I know of, it indicates the
precedence.

Ian

Lyuben Blagoev

unread,
Jul 20, 2017, 2:47:12 AM7/20/17
to golang-nuts
I think the behavior is defined with the following statement in the spec:

Primary expressions are the operands for unary and binary expressions. 

x[0] is a primary expression, so it is the operand for the unary expression, thus the expression is avaluated as *(x[0]).


> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.

adrian...@bluesombrero.com

unread,
Jul 20, 2017, 12:47:44 PM7/20/17
to golang-nuts
That makes sense, thank you! It does make it a little confusing that a special case was made for pointers to arrays that violates that rule, but it's a pretty rare use case anyway.

Thanks for pointing this out, it was driving me crazy.

> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages