ZHCADC3B February 2019 – October 2023
大于 32 位的结构体(包括类)和联合体通过引用进行传递和返回。请参阅节 2.6以了解其他一些情况,此时在使用 FPU32 或 FPU64 时,结构体和联合体通过值进行传递。
若要通过引用传递结构体或联合体,调用方需将其地址放置在适当的位置:根据其在实参列表中的位置,放在寄存器中或栈中。为了保留值传递语义(C 和 C++ 的要求),被调用者可能需要制作自己的指向对象副本。在某些情况下,被调用者不需要制作拷贝,如被调用者是叶子函数并且它不修改指向对象。
如果被调用的函数返回大于 32 位的结构体或联合体,调用者必须传递一个附加实参,其中包含返回值的目标地址,或者,如果未使用返回值,则返回 NULL。
此附加实参作为隐式第一个实参在第一个实参寄存器中传递。被调用方通过将对象复制到给定地址来返回对象。如果需要,调用方负责分配存储器。通常,这涉及在栈上保存空间,但在某些情况下,可以传递已经存在的对象的地址,而无需分配。例如,如果 f 返回一个结构体,则可以通过在第一个实参寄存器中传递 &s 来编译赋值 s = f()。
示例
C 源代码:
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);
}
“降低”C 代码:(高级别 C 代码转换为低级别 C 代码)
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);
}