[解決済み] ネストされた'for'ループの数に限界はありますか?
質問
何事にも限度がありますから、ネストされた
for
ループの数に制限があるのか、それともメモリさえあれば追加できるのか、Visual Studioコンパイラはそのようなプログラムを作成できるのでしょうか?
もちろん、64以上のネストされた
for
ループはデバッグに便利ではありませんが、それは可能でしょうか?
private void TestForLoop()
{
for (int a = 0; a < 4; a++)
{
for (int b = 0; b < 56; b++)
{
for (int c = 0; c < 196; c++)
{
//etc....
}
}
}
}
どのように解決するのですか?
思い切って投稿してみましたが、その答えは
550と575の間
Visual Studio 2015 のデフォルト設定による
私は、ネストされた
for
のループを生成する小さなプログラムを作りました...
for (int i0=0; i0<10; i0++)
{
for (int i1=0; i1<10; i1++)
{
...
...
for (int i573=0; i573<10; i573++)
{
for (int i574=0; i574<10; i574++)
{
Console.WriteLine(i574);
}
}
...
...
}
}
500回のネストされたループの場合、プログラムはまだコンパイル可能です。575ループの場合、コンパイラはベイルアウトします。
警告 AD0001 Analyzer 'Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames.CSharpSimplifyTypeNamesDiagnosticAnalyzer' はメッセージ 'InsufficientStackException' タイプの例外を投げました 'プログラムを安全に実行し続けるための十分なスタックがありません' と書いてあります。これは、コールスタック上にあまりにも多くの関数があるか、スタック上の関数があまりにも多くのスタックスペースを使用している場合に発生する可能性があります'。
というコンパイラーメッセージが表示されます。
<ブロッククオートerror CS8078: 式が長すぎるか複雑すぎるため、コンパイルできません。
もちろん、これは
純粋に仮説であり
の結果です。もし一番内側のループが
Console.WriteLine
を行う場合、スタックサイズを超える前に可能なネストされたループの数は少なくなるかもしれません。また、これは厳密には技術的な制限ではないかもしれません。エラーメッセージで言及されている "Analyzer"、または(必要に応じて)結果の実行可能ファイルの最大スタックサイズを増やすための隠れた設定があるかもしれないという意味でもです。しかし、この部分の回答は、C# を深く知っている人に任されています。
アップデート
に対する対応として の質問に対して :
この回答を拡大して、575個のローカル変数をスタック上に置くことができるかどうかを実験的に証明することに興味があります。 ではない でない場合、575 個のローカル変数をスタックに置くことができるかどうか、および/または、575個の ネストされていない を一つの関数に入れることができるかどうか。
どちらのケースでも、答えは「はい、可能です」です。メソッドに575の自動生成ステートメントを記入する場合
int i0=0;
Console.WriteLine(i0);
int i1=0;
Console.WriteLine(i1);
...
int i574=0;
Console.WriteLine(i574);
であれば、まだコンパイル可能です。それ以外のことは驚きの連続だったでしょう。必要なスタックサイズは
int
変数に必要なスタックサイズは、わずか2.3KBです。しかし、私は好奇心旺盛で、さらなる限界を試すために、この数字を増やしました。最終的に、それは
ではなく
がコンパイルされ、エラーが発生しました。
エラーCS0204。コンパイラが生成したものを含め、65534個のローカルしか許可されません
というのは興味深い点ですが、すでに他の場所で観察されています。 メソッド内の変数の最大数
同様に、575
ネストされていない
for
のような-loopがあります。
for (int i0=0; i0<10; i0++)
{
Console.WriteLine(i0);
}
for (int i1=0; i1<10; i1++)
{
Console.WriteLine(i1);
}
...
for (int i574=0; i574<10; i574++)
{
Console.WriteLine(i574);
}
も同様にコンパイルすることができる。ここでは、その限界を探るために、さらにこのループを作成しました。特に、この場合のループの変数は、自分自身の
{ block }
. しかし、それでも65534以上はありえません。最後に、私はパターンの40000ループからなるテストを追加しました。
for (int i39999 = 0; i39999 < 10; i39999++)
{
int j = 0;
Console.WriteLine(j + i39999);
}
は、追加の変数 で を含んでいますが、これらも同様に "locals" としてカウントされるようで、これをコンパイルすることはできませんでした。
ということで、まとめます。550 という限界は、確かに ネストの深さ が原因です。これはまた、エラーメッセージによって示されました
error CS8078: 式が長すぎるか複雑すぎるため、コンパイルできません。
その エラー CS1647 のドキュメント 残念ながら (しかし当然ながら)、複雑さの測定は指定されておらず、実用的なアドバイスが与えられているだけです。
あなたのコードを処理するコンパイラでスタックオーバーフローが発生しました。このエラーを解決するには、コードを簡略化してください。
これを再度強調するために
を深くネストした特殊なケースについては
for
-ループの場合、このすべてはむしろ学術的で仮説的なものです。
. しかし、CS1647 のエラー メッセージを Web で検索すると、おそらく意図的に複雑なものではなく、現実的なシナリオで作成されたコードにこのエラーが表示されるケースがいくつか見つかります。
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] C#がforeachで変数を再利用するのは理由があるのか?
-
[解決済み] .NET String.Format()で数値の千の位にカンマを追加する
-
[解決済み] ( for... in ) と ( for... of ) の文の違いは何ですか?
-
[解決済み] なぜpythonはforやwhileループの後に'else'を使うのですか?
-
[解決済み] Windowsにはなぜ260文字というパスの長さの制限があるのですか?
-
[解決済み] 複数のネストされた「for」ループを終了するためにbreakを使用できますか?
-
[解決済み] ネストされたループに代わるより高速な方法?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】統合マネージドパイプラインモードで適用されないASP.NETの設定が検出された
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み] [Solved] アセンブリ System.Web.Extensions dll はどこにありますか?
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】aspNetCore 2.2.0 - AspNetCoreModuleV2 エラー
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?