2

Code

func deferModifyReturnValue() int {
    x := 0
    defer func() {
        x += 1 // executed before return,
    }()
    return x
}

func deferModifyNamedReturnValue() (x int) {
    defer func() {
        x += 1 // executed before return,
    }()
    return
}

func TestDeferModifyReturnValue(t *testing.T) {
    assert.Equal(t, 0, deferModifyReturnValue())
    assert.Equal(t, 1, deferModifyNamedReturnValue())
}

Question

The test passes.

I can understand why the deferModifyNamedReturnValue() return 1, because defer modify it right before return.

But, how the deferModifyReturnValue() return 0? Does it make a copy to stack before the modification?

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Eric
  • 22,183
  • 20
  • 145
  • 196
  • 4
    From the [documentation](https://go.dev/ref/spec#Defer_statements): _"deferred functions are executed after any result parameters are set by that return statement"_ – JimB Jan 18 '22 at 17:59
  • @JimB Ok, so you mean: A) in the non-named case, a copy to stack is made before the defer function is executed, thus return value is not effected by defer; B) and in the `named return value` case, since the return value is already defined & set, thus the defer take effect. Right ? – Eric Jan 18 '22 at 18:11
  • When the result parameter is not named, creating a local variable has no connection to the return value. It doesn't matter if a deferred function changes the value of `x` after the `return` statement: the variable has nothing to do with the value being returned. If `x` itself is the result parameter, its value will be used when the function ends. If a deferred function modifies it after a `return`, the new value will be returned. – icza Jan 18 '22 at 18:13
  • @icza your comment doesn't actually answer my doubt clearly, and the linked question in duplication is not identical to my question neither. – Eric Jan 18 '22 at 18:16
  • 9
    Whether the result of the return's expression is stored on the stack is irrelevant (can be implementation specific). What matters is that the expression is evaluated when the `return` statement is executed. Deferred functions run _after_ this. In the first example the `x` variable is **not** the result parameter, so again, changing it has no effect on the value being returned. – icza Jan 18 '22 at 18:19

0 Answers0