Skip to content

proposal: spec: disallow taking the addresses of loop variables #20725

Closed
@bisgardo

Description

@bisgardo

Consider a range loop:

for k, v := range vals {
  // ...
}

Since the variables k and v are not redefined for each iteration of the loop, their addresses are the same in each iteration. These addresses are therefore very unlikely to be useful, and the following more explicit alternatives are IMO clearer and more robust to refactorings anyway:

  • Instead of overwriting the value by passing its address to a helper function, define a new variable instead:

    for _, v := range vals {
      // Alternative to `writeStuffTo(&v)`:
      var v2 typeOfV
      writeStuffTo(&v2)
    }
    
  • In order to reference the object in the current iteration of the loop, copy it or access the iterated slice directly:

    for i, v := range vals {
      // Calling `sendSomewhere(&v)` here would likely be a bug
      v := v
      sendSomewhere(&v)       // Alternative 1: Use copied value
      sendSomewhere(&vals[i]) // Alternative 2: Take address of currently iterated value
    }
    

I would argue that taking the addresses of range variables is so rarely useful that it would be good to require the intent to be made explicit as follows:

var v typeOfV
vp := &v
for _, v = range vals {
	// Use `vp` if you must...
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions