gcc编译
gcc main.c
反编译
objdump -d a.out
传值源代码
typedef struct{
int arr[10000];
}node;
void func(node n){}
int main(){
node n;
func(n);
return 0;
}
传值部分汇编代码
100000f81: 48 89 e5 movq %rsp, %rbp
100000f84: 48 81 ec 90 38 01 00 subq $80016, %rsp
100000f8b: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
100000f92: 48 89 e0 movq %rsp, %rax
100000f95: b9 88 13 00 00 movl $5000, %ecx
100000f9a: 48 8d b5 b8 63 ff ff leaq -40008(%rbp), %rsi
100000fa1: 48 89 c7 movq %rax, %rdi
100000fa4: f3 48 a5 rep movsq (%rsi), %es:(%rdi)
100000fa7: e8 c4 ff ff ff callq -60 <_func>
传引用源代码
typedef struct{
int arr[10000];
}node;
void func(node *n){}
int main(){
node n;
func(&n);
return 0;
}
传引用部分汇编代码
00000f80: 55 pushq %rbp
100000f81: 48 89 e5 movq %rsp, %rbp
100000f84: 48 81 ec 50 9c 00 00 subq $40016, %rsp
100000f8b: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
100000f92: 48 8d bd b8 63 ff ff leaq -40008(%rbp), %rdi
100000f99: e8 d2 ff ff ff callq -46 <_func>
分析
观察传值汇编代码可以发现,编译器分配了80016个字节,是node结点所需字节数(40000)的两倍(多出来的16字节是因为编译器通常会多分配一些字节,多出的字节是不固定的)。而传引用的情况下编译器只分配了40016个字节。显然,如果我们使用传值,编译器将把node赋值一遍传递给func函数。如果不是刻意为之,开发场景中需要进行这样的拷贝,传值是不可取的,它会浪费栈空间。