# Go 1.2 Field Selectors and Nil Checks

Author: Russ Cox

Last updated: July 2013

Discussion at https://go.dev/issue/4238.

Originally at https://go.dev/s/go12nil.

Implemented in Go 1.2 release.

## Abstract

For Go 1.2, we need to define that, if `x` is a pointer to a struct
type and `x == nil`, `&x.Field` causes a runtime panic rather than
silently producing an unusable pointer.

## Background


Today, if you have:

```Go
package main

type T struct {
        Field1 int32
        Field2 int32
}

type T2 struct {
        X [1<<24]byte
        Field int32
}

func main() {
        var x *T
        p1 := &x.Field1
        p2 := &x.Field2
        var x2 *T2
        p3 := &x2.Field
}
```

then:

* `p1 == nil`; dereferencing it causes a panic
* `p2 != nil` (it has pointer value 4); but dereferencing it still
  causes a panic
* p3 is not computed: `&x2.Field` panics to avoid producing a pointer
  that might point into mapped memory.

The spec does not define what should happen when `&x.Field` is evaluated
for `x == nil`.
The answer probably should not depend on `Field`’s offset within the
struct.
The current behavior is at best merely historical accident; it was
definitely not thought through or discussed.

Those three behaviors are three possible definitions.
The behavior for `p2` is clearly undesirable, since it creates
unusable pointers that cannot be detected as unusable.
hat leaves `p1` (`&x.Field` is `nil` if `x` is `nil`) and `p3`
(`&x.Field` panics if `x` is `nil`).

An analogous form of the question concerns `&x[i]` where `x` is a
`nil` pointer to an array.
he current behaviors match those of the struct exactly, depending in
the same way on both the offset of the field and the overall size of
the array.

A related question is how `&*x` should evaluate when `x` is `nil`.
In C, `&*x == x` even when `x` is `nil`.
The spec again is silent.
The gc compilers go out of their way to implement the C rule (it
seemed like a good idea at a time).

A simplified version of a recent example is:

```Go
        type T struct {
                f int64
                sync.Mutex
        }

        var x *T

        x.Lock()
```

The method call turns into `(&x.Mutex).Lock()`, which today is passed
a receiver with pointer value `8` and panics inside the method,
accessing a `sync.Mutex` field.


## Proposed Definition

If `x` is a `nil` pointer to a struct, then evaluating `&x.Field`
always panics.

If `x` is a `nil` pointer to an array, then evaluating `&x[i]` panics
or `x[i:j]` panics.

If `x` is a `nil` pointer, then evaluating `&*x` panics.

In general, the result of an evaluation of `&expr` either panics or
returns a non-nil pointer.

## Rationale

The alternative, defining `&x.Field == nil` when `x` is `nil`, delays
the error check.
That feels more like something that belongs in a dynamically typed
language like Python or JavaScript than in Go.
Put another way, it pushes the panic farther away from the problem.

We have not seen a compelling use case for allowing `&x.Field == nil`.

Panicking during `&x.Field` is no more expensive (perhaps less) than
defining `&x.Field == nil`.

It is difficult to justify allowing `&*x` but not `&x.Field`.
They are different expressions of the same computation.

The guarantee that `&expr`—when it evaluates successfully—is always a
non-nil pointer makes intuitive sense and avoids a surprise: how can
you take the address of something and get `nil`?

## Implementation

The addressable expressions are: “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.”

The address of a variable can never be `nil`; the address of a slice
indexing operation is already checked because a `nil` slice will have
`0` length, so any index is invalid.

That leaves pointer indirections, field selector of struct, and index
of array, confirming at least that we’re considering the complete set
of cases.

Assuming `x` is in register AX, the current x86 implementation of case
`p3` is to read from the memory `x` points at:

```
	TEST 0(AX), AX
```

That causes a fault when `x` is nil.
Unfortunately, it also causes a read from the memory location `x`,
even if the actual field being addressed is later in memory.
This can cause unnecessary cache conflicts if different goroutines own
different sections of a large array and one is writing to the first
entry.

(It is tempting to use a conditional move instruction:

```
	TEST AX, AX
	CMOVZ 0, AX
```

Unfortunately, the definition of the conditional move is that the load
is unconditional and only the assignment is conditional, so the fault
at address `0` would happen always.)

An alternate implementation would be to test `x` itself and use a
conditional jump:

```
	TEST AX, AX
	JNZ ok  (branch hint: likely)
	MOV $0, 0
ok:
```

This is more code (something like 7 bytes instead of 3) but may run
more efficiently, as it avoids spurious memory references and will be
predicted easily.

(Note that defining `&x.Field == nil` would require at least that much
code, if not a little more, except when the offset is `0`.)

It will probably be important to have a basic flow analysis for
variables, so that the compiler can avoid re-testing the same pointer
over and over in a given function.
I started on that general topic a year ago and got a prototype working
but then put it aside (the goal then was index bounds check
elimination).
It could be adapted easily for nil check elimination.
