C编译器如何向函数传递/返回struct / union?在函数调用之前是否将结构推送到堆栈只是传递给函数的struct的引用?
同样的问题适用于退货。函数究竟返回了什么?
typedef struct {
long m4;
long m3;
long m2;
long m1;
} ext_components_t;
typedef union {
long array[sizeof(int_components_t)];
int_components_t comp;
} int_components_u;
typedef union {
long array[sizeof(ext_components_t)];
ext_components_t comp;
} ext_components_u;
#pragma never_inline
ext_components_u transfer(int_components_u m)
{
ext_components_u out;
out.comp.m1 = 10*m.comp.a+11*m.comp.b+12*m.comp.c;
out.comp.m2 = 20*m.comp.a+21*m.comp.b+22*m.comp.c;
out.comp.m3 = 30*m.comp.a+31*m.comp.b+32*m.comp.c;
out.comp.m4 = 40*m.comp.a+41*m.comp.b+42*m.comp.c;
return out;
}
volatile int_components_u x;
volatile ext_components_u y;
void main()
{
y = transfer(x);
}
这是我的猜测(伪代码):
push_stack(x.array[0])
push_stack(x.array[1])
push_stack(x.array[2])
call transfer
y.array[0] = shift_stack()
y.array[1] = shift_stack()
y.array[2] = shift_stack()
y.array[3] = shift_stack()
或另一种解决方案可能是:
call transfer(&x)
y.array[0] = shift_stack()
y.array[1] = shift_stack()
y.array[2] = shift_stack()
y.array[3] = shift_stack()
答案 0 :(得分:6)
在C中,函数的所有参数都按值传递。这意味着结构和联合在传递给函数时会被复制。如何处理复制是特定于实现的,但最常见的方法是在堆栈上分配空间并将结构/联合的内容复制到该空间中。
返回数据也是如此,它是按值返回的(即复制)。
这里有一点需要注意,那就是C没有通过引用传递。传递指针时,它是通过值传递的指针,即它被复制。
但是,您可以使用指向模拟的引用按引用传递。
答案 1 :(得分:2)
如何传递结构并返回结构是依赖于实现的。通常它们被复制到堆栈中。参数尽可能在寄存器中传递(速度)。
实现可以以不同的方式传递int和仅包含int成员的结构。同样的规则也适用于工会。
有些书说“通过将参数从右向左推入堆栈,将参数传递给被调用的函数”。这是过度紧张。 (来自Peter Van der Linden的专家C编程Deep C秘密)