Я выхожу на конечности путем размещения, но я думаю, что ответ:
Между 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» бросил исключение типа «System.InsufficientExecutionStackException» с сообщением «Недостаточно стека продолжить выполнение безопасно. Это может произойти из-за слишком большого количества функций в стеке вызовов или функции в стеке, используя слишком много пространства стека. '.
с основным сообщением компилятора
ошибка CS8078: Выражение является слишком длинным или сложным для компиляции
Конечно, это чисто гипотетический результат. Если самый внутренний цикл содержит больше, чем Console.WriteLine
, тогда может быть меньше вложенных циклов до превышения размера стека.Кроме того, это может быть не строго технический предел в том смысле, что могут быть скрытые настройки для увеличения максимального размера стека для «Анализатора», упомянутого в сообщении об ошибке, или (если необходимо) для результирующего исполняемого файла. Однако эта часть ответа остается для людей, которые знают C# по глубине.
Update
В ответ на question in the comments:
мне было бы интересно увидеть этот ответ расширен, чтобы «доказать» экспериментально, можно ли ставить 575 локальные переменные в стеке, если они 're не Используется в петлях и/или вы можете положить 575 не вложенные для петель в одной функции
В обоих случаях ответ: Да, это возможно. При заполнении метода 575 автоматически сгенерированных операторов
int i0=0;
Console.WriteLine(i0);
int i1=0;
Console.WriteLine(i1);
...
int i574=0;
Console.WriteLine(i574);
он все еще может быть скомпилирован. Все остальное меня удивило бы. Размер стека, необходимый для переменных int
, составляет всего 2,3 КБ. Но мне было любопытно, и для того, чтобы проверить дальнейшие ограничения, я увеличил это число. В конце концов, он сделал не компиляции, вызывая ошибку
ошибка CS0204: только 65534 местных жителей, в том числе, генерируемый компилятором, допускаются
который интересный момент, но уже наблюдали в других местах: Maximum number of variables in method
Аналогично, 575 невложенныхfor
-loops, как и в
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);
}
также может быть скомпилирован. Здесь я также попытался найти предел и создал больше этих циклов. В частности, я не был уверен, что переменные цикла в этом случае также считают als «locals», потому что они находятся в их собственном { block }
. Но все же более 65534 невозможно. Наконец, я добавил тест, состоящий из 40000 петель узора
for (int i39999 = 0; i39999 < 10; i39999++)
{
int j = 0;
Console.WriteLine(j + i39999);
}
, который содержал дополнительную переменную в цикла, но они, кажется, считаются «местных», а также, и не было возможности собрать это.
Итак, подведем итог: Предел ~ 550 действительно вызвано вложенности петель.Это также было указано в сообщении об ошибке
ошибка CS8078: выражение слишком длинное или сложное для компиляции
documentation of error CS1647, к сожалению (но по понятным причинам) не определяет «измерение» сложности, но дает только прагматичный совет
В вашем компиляторе произошел переполнение стека. Чтобы устранить эту ошибку, упростите свой код.
Чтобы подчеркнуть это снова: Для конкретного случая глубоко вложенных for
-loops, все это скорее академическое и гипотетический. Но поиск в Интернете сообщения об ошибке CS1647 показывает несколько случаев, когда эта ошибка появилась для кода, который, скорее всего, не был намеренно сложным, но создан в реалистичных сценариях.
Я согласен с другими, но когда у вас уже есть такая ситуация, вы должны поместить внутренние петли во внешние методы. По крайней мере, это было бы читаемо – Sasha
Вы программист на компьютере: ответьте на свой вопрос с помощью компьютерного программирования. Напишите программу, которая генерирует, компилирует и запускает программы с 1, 2, 4, 8, 16, 32, ... вложенными циклами, и вы очень быстро узнаете, есть ли предел. –
# 1. ОП не указал, что это никак не связано с производственным кодом, а не только с гипотетическим вопросом типа «что-если». # 2. Независимо от того, сколько вложенных циклов, которые делает OP во время экспериментов, они никогда не достигнут бесконечности; независимо от того, как далеко продвигает OP, единственный способ, который когда-либо докажет, есть ли предел, если и когда он действительно сломается. – Panzercrisis