0

In my code I try to use numAddr to record the change of num after the defer statement

func deferRun() {
    num := 1
    numAddr := &num
    defer fmt.Printf("num is %d", *numAddr)
    num = 2
    return
}

func main() {
    deferRun()
}

but I get num is 1 instead of 2, why does the defer function use the value instead of address of *numAddr?

then I try another way

func deferRun() {
    num := 1
    numAddr := &num
    defer func(intAddr *int){
        fmt.Printf("num is %d", *numAddr)
    }(numAddr)
    
    num = 2
    fmt.Println("num is", *numAddr)
    return
}

func main() {
    deferRun()
}

This time it works and I get num is 2, so I think maybe defer fmt.Printf(something) stored the string immediately when it was declared and the numAddr is not used when the defer function actually run?

  • Duplicate. `*numAddr` is evaluated when when the defer line is executes. At that time `*numAddr == 1` . – Volker Mar 05 '23 at 07:53

1 Answers1

2

Interesting question. To answer the question, you must know a rule, as in this Go tutorial https://go.dev/tour/flowcontrol/12

The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns..

Example 1: Telling the defer function to print value located in a specified memory address.

func deferRun() {
    num := 1
    numAddr := &num //address of variable num in stack memory, 0xc000076f38 for example
    defer func(intAddr *int){
        fmt.Printf("num is %d", *numAddr)
    }(numAddr) //Hey Go, when the surrounding function returns, print the value located in this address (numAddr=0xc000076f38)
    num = 2 //Now the value located in address 0xc000076f38 is 2
    return  
}

Output will be 2.

Example 2: Telling the defer function to print a specified value.

func deferRun() {
    num := 1
    numAddr := &num //address of variable num in stack memory, 0xc000076f38 for example
    defer fmt.Printf("num is %d", *numAddr) //Hey Go, when the surrounding function returns, print the this value *numAddr (*numAddr is 1 for now)
    num = 2 //Now the value located in address 0xc000076f38 is 2 but you told the defer function to print 1 before
    return  
}

Output will be 1.

TaQuangTu
  • 2,155
  • 2
  • 16
  • 30