Search code examples
pointersgoreferencememory-addressdereference

Why is a pointer to int initialised with “*int” and not “&int”?


For example, when initialising a pointer to an int, we use:

var pointer *int

Why is the syntax not instead:

var pointer &int

To me, the second version would have made more sense as it would read like “variable ‘pointer’ is a memory address of an int”

Or to put it another way, I find it confusing that the “*” is used for both for defining a memory address type (as above), and for dereferencing, e.g. *pointer = 123

Is this as confusing as it seems, or am I missing something here?


Solution

  • & is an address operator, not a type.

    For an operand x of type T, the address operation &x generates a pointer of type *T to x.

    But it is true * is also used as a pointer indirection:

    For an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x

    As seen in Tour of Go, * references both a type and an operator.

    This thread from 2016 asks a similar question.

    The pointer syntax is just copied from C, of course.
    See also Go's Declaration Syntax
    If we had used '&', then a Go pointer would look like a C++ reference.

    And:

    *int defines a pointer type and then can be used with or without the * on the variable.

    • With the * you access the value pointed to.
    • Without, you access the memory address pointed to.

    & retrieves a memory address from a variable.

    An address is not a pointer and vice versa.
    You define a pointer using a memory address.

    var x int = 10    // declare an int variable `x` holding the value 10.
    var y *int = &x  // Create a pointer `y` *using* the memory address of `x`.
    

    *y will have the value 10.
    y will be the memory address of x


    See more in "Pointers in Go" from Dave Cheney:

    Go pointers, like C pointers, are values that, uh, point to other values. This is a tremendously important concept and shouldn’t be considered dangerous or something to get hung up on.

    A pointer is a value that points to the memory address of another variable.

    But:

    you cannot alter the address p points to unless you assign another address to it
    No: var p *int; p++ possible.

    (See also "Go at Google: Language Design in the Service of Software Engineering")

    Once a value is assigned to a pointer, with the exception of nil, Go guarantees that the thing being pointed to will continue to be valid for the lifetime of the pointer.