4

我刚刚发现stackallocC# 的符号有一个令人难以置信的怪癖,请看下面的代码:

//          int *p;
//          p = stackalloc int[42];  // won't work! 
//  Error CS1525: Unexpected symbol `stackalloc' (CS1525) 

            int *p = stackalloc int[42]; //works

我的意图是在这样的三元表达式中使用 stackalloc:

int *p = size > 0xFFFFF ? (int*)Marshal.AllocHGlobal(size).ToPointer() : stackalloc int[size];

编译器完全出乎意料的打击让我震惊。如果有人能对这种奇怪的行为有所了解,我将不胜感激。我已经在单声道和 .net 上对其进行了测试,但都不起作用。

4

3 回答 3

9

http://msdn.microsoft.com/en-us/library/cx9s2sy4(v=vs.100).aspx
只有在声明和初始化局部变量时才能使用 stackalloc。

于 2012-11-09T12:47:07.510 回答
5

人们已经回答了这个问题,您只能在声明和初始化局部变量时使用它:http: //msdn.microsoft.com/en-us/library/cx9s2sy4 (v=vs.110).aspx 。

但是,如果您想知道这是什么原因,那就是词法作用域。局部变量声明创建一个包含一个或多个基本块的词法范围。CLR 要求堆栈指针在每个此类基本块的开头和结尾处的位置相同。控制转移语句只能跳转到基本块的第一条指令。

当您使用stackalloc时,编译器需要通过递减堆栈指针并在分配的变量超出范围时再次递增它来在堆栈上腾出一些空间。

如果您在表达式评估中,堆栈上会有临时值,那么编译器应该将该变量放在哪里?在方法的开头分配它不是一种选择,因为您可以使用表达式来指定大小。

因此,您必须明确告诉编译器您希望将该变量分配到何处以及应保留内存多长时间。

于 2012-11-09T14:48:38.243 回答
0

可以理解这是一种古怪的行为......我不知道为什么,但它记录在 MSDN 上

看这里:

http://msdn.microsoft.com/en-us/library/cx9s2sy4.aspx

于 2012-11-09T12:53:06.347 回答