SLAA534A June 2013 – June 2020
Structures (including classes) and unions are passed and returned by reference.
To pass a structure or union by reference, the caller places its address in the appropriate location: either in a register or on the stack, according to its position in the argument list. To preserve pass-by-value semantics (required for C and C++), the callee may need to make its own copy of the pointed-to object. In some cases, the callee need not make a copy, such as if the callee is a leaf and it does not modify the pointed-to object.
The caller must pass an additional argument containing a destination address for the returned value, or NULL if the returned value is not used.
This additional argument is passed in the first argument register as an implicit first argument. The callee returns the object by copying it to the given address. The caller is responsible for allocating memory if required. Typically this involves reserving space on the stack, but in some cases the address of an already-existing object can be passed and no allocation is required. For example, if f returns a structure, the assignment s = f() can be compiled by passing &s in the first argument register.
Examples
C source code:
struct S { char big[100]; } g;
struct S accepts_and_returns_struct(struct S s)
{
s.big[0] = 1;
return s;
}
void caller(void)
{
struct S w;
w.big[0] = 0;
g = accepts_and_returns_struct(w);
}
"Lowered" C code: (higher-level C code converted to lower-level C code)
struct S { char big[100]; } g;
void accepts_and_returns_struct(struct S *dst, struct S *sptr)
{
struct S s;
s = *sptr;
s.big[0] = 1;
if (dst) *dst = s;
}
void caller(void)
{
struct S w;
w.big[0] = 0;
accepts_and_returns_struct(&g, &w);
}