4

C#の表記に信じられないほどの癖があることを発見しましstackallocた。次のコードを参照してください。

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

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

私の意図は、次のような3項式でstackallocを使用することです。

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

まったく予想外のコンパイラの攻撃は私に大きな衝撃を与えました。誰かがこの奇妙な行動に光を当てることができれば本当にありがたいです。私はmonoと.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

しかし、この理由が何なのか疑問に思っているなら、それは字句スコープです。ローカル変数宣言は、1 つ以上の基本ブロックを含むレキシカル スコープを作成します。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 に答える