Я рискну, опубликовав это, но думаю, что ответ таков:
Между 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 «Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames.CSharpSimplifyTypeNamesDiagnosticAnalyzer» выдал исключение типа «System.InsufficientExecutionStackException» с сообщением «Недостаточно стека для продолжения безопасного выполнения программы. Это может произойти из-за того, что слишком много функций в стеке вызовов или функция в стеке использует слишком много места в стеке. '.
с базовым сообщением компилятора
ошибка CS8078: выражение слишком длинное или сложное для компиляции
Конечно, это чисто гипотетический результат. Если самый внутренний цикл выполняет больше, чем a Console.WriteLine
, то может быть возможно меньше вложенных циклов до того, как размер стека будет превышен. Кроме того, это не может быть строго техническим ограничением в том смысле, что могут быть скрытые настройки для увеличения максимального размера стека для «Анализатора», упомянутого в сообщении об ошибке, или (при необходимости) для результирующего исполняемого файла. Однако эта часть ответа остается на усмотрение людей, глубоко знающих C #.
Обновить
В ответ на вопрос в комментариях :
Мне было бы интересно увидеть, как этот ответ будет расширен, чтобы «экспериментально доказать», можно ли поместить 575 локальных переменных в стек, если они не используются в циклах for, и / или можно ли поместить 575 не вложенных циклов for в единственная функция
В обоих случаях ответ: да, это возможно. При заполнении метода 575 автоматически сгенерированными операторами
int i0=0;
Console.WriteLine(i0);
int i1=0;
Console.WriteLine(i1);
...
int i574=0;
Console.WriteLine(i574);
его еще можно скомпилировать. Все остальное меня бы удивило. Размер стека, который требуется для int
переменных, составляет всего 2,3 КБ. Но мне было любопытно, и я увеличил это число, чтобы проверить дальнейшие пределы. В конце концов, он не скомпилировался, что привело к ошибке.
ошибка CS0204: разрешены только 65534 локальных, включая сгенерированные компилятором
что является интересным моментом, но уже наблюдалось в другом месте: максимальное количество переменных в методе
Аналогичным образом , 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);
}
также могут быть скомпилированы. Здесь я также попытался найти предел и создал больше таких циклов. В частности, я не был уверен, считаются ли переменные цикла в этом случае также «локальными», потому что они сами по себе { block }
. Но все равно больше 65534 невозможно. Напоследок добавил тест, состоящий из 40000 петель узора
for (int i39999 = 0; i39999 < 10; i39999++)
{
int j = 0;
Console.WriteLine(j + i39999);
}
которые содержат дополнительную переменную в цикле, но они, кажется, тоже считаются «локальными», и это было невозможно скомпилировать.
Итак, подведем итог: ограничение ~ 550 действительно вызвано глубиной вложенности петель. На это также указывает сообщение об ошибке
ошибка CS8078: выражение слишком длинное или сложное для компиляции
К сожалению, в документации по ошибке CS1647 (но по понятным причинам) не указывается «измерение» сложности, а дается только практический совет.
В компиляторе, обрабатывающем ваш код, произошло переполнение стека. Чтобы устранить эту ошибку, упростите свой код.
Еще раз подчеркнем: для частного случая глубоко вложенных for
циклов все это скорее академическое и гипотетическое . Но веб-поиск сообщения об ошибке CS1647 показывает несколько случаев, когда эта ошибка появлялась для кода, который, скорее всего, не был намеренно сложным, а был создан в реалистичных сценариях.