Go Function Call Convention

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Contrast C++,go does not support overloads and default parameters, supports variable length variables, multiple return values, anonymous functions, and closures.

C in-stack order and return value

There was a question before, why go supports multiple return values, and C does not. First of all, review the stack space of the C function call Programmer's self-accomplishment ch10-2. The function calls the first parameter and return address into the stack, followed by the stack old EBP and the register to be saved, followed by local variables and other data inside the function. Two pointers EBP and ESP point to the return address and the top of the stack, respectively.

There are several cases where the return value of a function is passed. If it is less than 4 bytes, the return value is stored in the EAX register, which is read by the function caller EAX. Returns a value of 5 to 8 bytes, combined with EAX and edx. If more than 8 bytes, first on the stack to open up a portion of the space temp, the address of the Temp object as a hidden parameter into the stack. When the function returns, copies the data to the Temp object and eax the address of the Temp object to the register. The caller copies the contents from the Temp object pointed to by EAX.

Multiple return value implementations of Go

When C requires multiple return values, it is usually shown that the address where the return value is stored is passed as a parameter to the function. Go's calling convention differs from c, where go puts Ret1 and Ret2 into the stack before the argument arg1 arg2 and retains the empty space, and the callee places the return value on the two slots.

void f(int arg1, int arg2, int *ret, int *ret2)func f(arg1, arg2 int) (ret1, ret2 int)

So either go or C, in order to avoid the object copy returned by the function, it is best not to return large objects.

Anonymous functions and closures

An anonymous function can be assigned to a variable as a struct field or passed in a channel. The anonymous function is assigned to the F variable as the return value, and you can see that the info locals content of the F variable is an address when debugging through GDB, and info symbol [addr] you can see that the address points to the symbol in the symbol table main.test.func1.f . the returned anonymous function is an object that holds the address of an anonymous function .

func test() func(int) int {return func(x int) int {x += xreturn x}}f := test()f(100) // output: 200

Closures are the concept of functional languages. The same closure is an object that contains the address of the FuncVal{ func_addr, closure_var_point} function and the addresses of the variables to which it is referenced. Now there is a problem, if the variable x is allocated on the stack, the function test returns after the corresponding stack is invalidated, test returns the anonymous function of the variable x will refer to a failed position. So variables referenced in the closure environment are not allocated on the stack. The go compiler automatically identifies the scope of the variable through the escape analysis , allocating memory on the heap rather than on the stack of function f.

Escape analysis can explain why go can return the address of a local variable, and C does not.

func test() func() {    x := 100    fmt.Printf("x (%p) = %d\n", &x, x)    return func() {        fmt.Printf("x (%p) = %d\n", &x, x)    }}f := test()f() // get same output

Reference article Go Basics anonymous function and closure function

Defer deferred call

The realization of defer

The Goroutine control structure has a table that records the defer expression, where the compiler inserts the command call Runtime.deferprocwhere defer appears, and it records the defer expression in the table. The expression is then executed from the defer table before the function returns, and the inserted instruction is call Runtime.deferreturn.

Defer and return

The meaning that defer executes before return is that the function returns a value assignment first, then calls the defer expression, and finally executes the return. The following is an excerpt from Go-internals, which summarizes the use of defer pits. Defer is actually called before return, but since the return statement is not an atomic instruction, defer is inserted between the assignment and the RET, so there may be a chance to change the final return value.

func f() (result int) {    defer func() {   // result = 0        result++     // result++    }()              // return 1    return 0}
func f() (r int) {     t := 5           // r = t = 5     defer func() {   // t = t + 5 = 10       t = t + 5      // return 5     }()     return t}
func f() (r int) {    defer func(r int) {  // r = 1          r = r + 5      // internal r = 6    }(r)                 // return 1    return 1}

This behavior was found when the error output was formatted.

Defer and closures

Defer call parameter x is evaluated or copied at defer registration , so in the following example, X is still 10 at the end of the call, and because Y is a closure parameter, the closure is copied with the Y variable pointer , so the final Y is 120, which enables deferred reading. In practical applications, you can also use pointers to implement defer delay reading.

fund test() {  x, y := 10, 20  defer func(i int) {    fmt.Println("defer:", i, y) // output: 10 120  }(x)    x += 10  y += 100  fmt.Println(x, y) // output: 20 120}

Performance of Defer

A simple benchmarktest test found that misuse of defer could lead to performance problems, especially in cycle.

Reference article Go Learning notes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.