Struct Returns

Normally the compiler must first allocate space for the return value (1) and then to call the function (2). In phase (3) the return value is copied to the variable s. In the callee fun, during the return sequence, the Compiler must copy the return value ( 4, struct copy).

Depending on the size of the struct, this may be done inline. After return, the caller main must copy 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, and increase code size and memory usage.

Listing: Returning a struct can force the Compiler to produce lengthy code.


struct S fun(void)

  /* ... */

  return s; // (4)

}

void main(void) {

  struct S s;

  /* ... */

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

  /* ... */

}

With the example in the following listing, the Compiler just has to pass the destination address and to call fun (2). On the callee side, the callee copies the result indirectly into the destination (4). This approach reduces memory 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 (e.g., if the destination struct is modified in the callee).

Listing: A better way is to pass only a pointer to the callee for the return value.


void fun(struct S *sp) {

  /* ... */

  *sp = s; // (4)

}

void main(void) {

  S s;

  /* ... */

  fun(&s);  // (2)

  /* ... */

}