假设 Joachim 指出您的意思是 CMTimeRange someVariableName[3]...
两者都会在堆栈上分配内存。
我猜alloca() 将不得不在你的函数序言之后添加额外的代码来进行分配......函数序言是编译器自动生成的代码,用于在堆栈上创建空间。结果是,您的函数在编译后可能会稍微大一些,但不会大很多……一些额外的指令来修改堆栈指针和可能的堆栈帧。我猜如果它不在条件分支中,编译器可以优化调用,或者只是将它提升到条件分支之外?
我在没有优化的情况下在我的 MQX 编译器上进行了实验……它不是 Objective-c,只是 C,也是一个不同的平台,但希望这是一个足够好的近似值,并且确实显示了发出的代码的差异。我在堆栈上使用了两个带有大数组的简单函数,以确保必须使用堆栈空间(变量不能仅存在于寄存器中)。
显然不建议将大数组放在堆栈上...这仅用于演示目的。
unsigned int TEST1(unsigned int stuff)
{
unsigned int a1[100]; // Make sure it must go on stack
unsigned int a2[100]; // Make sure it must go on stack
a1[0] = 0xdead;
a2[0] = stuff + 10;
return a2[0];
}
unsigned int TEST2(unsigned int stuff)
{
unsigned int a1[100]; // Make sure it must go on stack
unsigned int *a2 = alloca(sizeof(unsigned int)*100);
a1[0] = 0xdead;
a2[0] = stuff + 10;
return a2[0];
}
生成了以下汇编程序:
测试1:
两个数组a1 和a2 都在函数序言中入栈...
0: 1cfcb6c8 push %fp
4: 230a3700 mov %fp,%sp
8: 24993901 sub3 %sp,%sp,100 # Both arrays put on stack
c: 7108 mov_s %r1,%r0
e: 1b38bf98 0000dead st 0xdead,[%fp,0xffff_fce0] ; 0xdead
16: e00a add_s %r0,%r0,10
18: 1b9cb018 st %r0,[%fp,0xffff_fe70]
1c: 240a36c0 mov %sp,%fp
20: 1404341b pop %fp
24: 7ee0 j_s [%blink]
测试2:
在序言中只有数组a1被放入堆栈...必须生成额外的代码行来处理alloca。
0: 1cfcb6c8 push %fp
4: 230a3700 mov %fp,%sp
8: 24593c9c sub3 %sp,%sp,50 # Only one array put on stack
c: 240a07c0 mov %r4,%blink
10: 220a0000 mov %r2,%r0
14: 218a0406 mov %r1,0x190 # Extra for alloca()
18: 2402305c sub %sp,%sp,%r1 # Extra for alloca()
1c: 08020000r bl _stkchk # Extra for alloca()
20: 738b mov_s %r3,%sp # Extra, r3 to access write via pointer
22: 1b9cbf98 0000dead st 0xdead,[%fp,0xffff_fe70] ; 0xdead
2a: 22400280 add %r0,%r2,10
2e: a300 st_s %r0,[%r3] # r3 to access write via pointer
30: 270a3100 mov %blink,%r4
34: 240a36c0 mov %sp,%fp
38: 1404341b pop %fp
3c: 7ee0 j_s [%blink]
另外,alloca() 内存将通过指针访问(除非对此有聪明的编译器优化...我不知道),因此会导致实际的内存访问。自动变量可能会被优化为只是寄存器访问,这样会更好...编译器可以使用寄存器着色来确定哪些自动变量最好留在寄存器中,以及它们是否需要在堆栈上。
我快速搜索了 C99 标准(C11 大约是……我的参考资料有点过时了)。看不到对alloca 的引用,因此可能不是标准定义的函数。可能的劣势?