Unexpected behavior where panic raised in-between two phases of an assignment statement

161 views
Skip to first unread message

Kaiming Yang

unread,
Dec 28, 2024, 8:38:17 PM12/28/24
to golang-nuts
Hi everyone,

I'm trying to understand execution order of assignment statement, as spec mentioned:

> The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.

I crafted a example about it: https://go.dev/play/p/6RulNQwIk4n, the core of that example is this line:

phase_2, foo.bar.value = "??????", compute_value()

where `foo.bar.value` causes panic due to nil pointer.

The execution result shows `compute_value()` is invoked, but `phase_2` variable is not updated. Seems like the panic happened after phase 1 is complete but before phase 2 started. 

I assume the panic should happen in one of two phases, but not in-between. If panic happened in phase 1, `compute_value()` should not be invoked due to it happen later in same phase; If panic happened in phase 2, `phase_2` variable should have been changed already.

 Is the behavior working-as-indented? if so, what am I missing to understand it?

Thanks for any help!

Best,
Kaiming





Ian Lance Taylor

unread,
Dec 28, 2024, 9:11:52 PM12/28/24
to Kaiming Yang, golang-nuts
Thanks. This looks like a bug to me. I think the panic should occur
before compute_value is called. When I run your program with gccgo I
get

original
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4037fb]

goroutine 1 [running]:
main.main
foo.go:22

Want to open a bug report at https://go.dev/issue? Thanks.

Ian

Kaiming Yang

unread,
Dec 28, 2024, 10:01:10 PM12/28/24
to golang-nuts
Thanks for the confirmation, I created https://github.com/golang/go/issues/71054 for this.

Kaiming Yang

unread,
Dec 29, 2024, 2:13:38 AM12/29/24
to golang-nuts
An update from the bug:  Seems the behavior is WAI because the execution order of dereference and function calls are not defined. deference of `foo.bar` may happen before or after (which is this case) the function call of `compute_value()`

Spec states following about order of evaluation:

> when evaluating the operands of an expression, assignment, or return statement
> all function calls, method calls, receive operations, and binary logical operations are evaluated in lexical left-to-right order. 

Notably, there is no selector expression, pointer dereference expression (explicit or implicit) and indexing expression (mentioned as example in spec) in that list.

tapi...@gmail.com

unread,
Dec 30, 2024, 9:07:20 PM12/30/24
to golang-nuts
There is not a phase between in-between, Any evaluation must happen in either of the two phases.
Reply all
Reply to author
Forward
0 new messages