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.
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).
void myfun(struct S *sp) { /* ... */ *sp = s; // (4) } void main(void) { S s; /* ... */ myfun(&s); // (2) /* ... */ }