Struct Returns

When returning structs, the Compiler allocates space on the stack for the return value and then calls the function. Then the Compiler copies the return value to the variable s. During the return sequence, the Compiler copies the return value to myfun (refer to the listing displayed below).

Depending on the size of the struct, this may be done inline. After return, the caller main copies the result back into s. Depending on the Compiler or Target, it is possible to optimize some sequences (avoiding some copy operations). However, returning a struct by value may increase execution time, possibly increasing code and stack usage.

Listing: Returning a struct Forces the Compiler to Produce Lengthy Code
struct S 
myfun(void)
  /* ... */

  return s; // (4)

}

void main(void) {

  struct S s;

  /* ... */

  s = 
myfun();  // (1), (2), (3)

  /* ... */

}

With the following example, the Compiler passes the destination address and calls myfun. The callee, myfun, copies the result indirectly into the destination. This approach reduces stack usage, avoids copying structs, and results in denser code. Note that the Compiler may also inline the above sequence (if supported). But for rare cases the above sequence may not be exactly the same as returning the struct by value (for example, if myfun modifies the destination struct).

Listing: Pass a Pointer to the Callee for the Return Value
void 
myfun(struct S *sp) {
  /* ... */

  *sp = s; // (4)

} void main(void) {

  S s;

  /* ... */

  
myfun(&s);  // (2)

  /* ... */

}