Since everything has a limit, I was wondering if there is a limit to the number of nested for
loops or as long as I have memory, I can add them, can the Visual Studio compiler create such a program?
Of course a 64 or more nested for
loops would be not handy to debug, but is it doable?
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.... } } } }
Nested loops are frequently (but not always) bad practice, because they're frequently (but not always) overkill for what you're trying to do. In many cases, there's a much faster and less wasteful way to accomplish the goal you're trying to achieve.
See answer here: too many statically nested blocks python You cannot increase it as it is builtin to the python syntax. The limit applies to any kind of code stack (exceptions, loops, etc.) and is a decision by the designers (presumably to keep memory usage reasonable).
A method in Java can be up to a maximum of 64KB. So, you can have as many nested loops as long as they are under the 64KB of memory.
Two nested loops: O(n²) In the above nested loop example, outer loop is running n times and for every iteration of the outer loop, inner loop is running (n - i) times. So total number of nested loop iteration = (n - 1) + (n - 2) + (n - 3)…..
I'm going out on a limb by posting this, but I think that the answer is:
Between 550 and 575
with default settings in Visual Studio 2015
I created a small program that generates nested for
loops...
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); } } ... ... } }
For 500 nested loops, the program can still be compiled. With 575 loops, the compiler bails out:
Warning AD0001 Analyzer 'Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames.CSharpSimplifyTypeNamesDiagnosticAnalyzer' threw an exception of type 'System.InsufficientExecutionStackException' with message 'Insufficient stack to continue executing the program safely. This can happen from having too many functions on the call stack or function on the stack using too much stack space.'.
with the underlying compiler message
error CS8078: An expression is too long or complex to compile
Of course, this is a purely hypothetical result. If the innermost loop does more than a Console.WriteLine
, then fewer nested loops may be possible before the stack size is exceeded. Also, this may not be a strictly technical limit, in the sense that there may be hidden settings to increase the maximum stack size for the "Analyzer" that is mentioned in the error message, or (if necessary) for the resulting executable. This part of the answer, however, is left to the people who know C# in depth.
In response to the question in the comments :
I would be interested to see this answer expanded to "prove" experimentally whether you can put 575 local variables on the stack if they're not used in for-loops, and/or whether you can put 575 non-nested for-loops in a single function
For both cases, the answer is: Yes, it is possible. When filling the method with 575 auto-generated statements
int i0=0; Console.WriteLine(i0); int i1=0; Console.WriteLine(i1); ... int i574=0; Console.WriteLine(i574);
it can still be compiled. Everything else would have surprised me. The stack size that is required for the int
variables is just 2.3 KB. But I was curious, and in order to test for further limits, I increased this number. Eventually, it did not compile, causing the error
error CS0204: Only 65534 locals, including those generated by the compiler, are allowed
which is an interesting point, but has already been observed elsewhere: Maximum number of variables in method
Similarly, 575 non-nested for
-loops, as in
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); }
can be compiled as well. Here, I also tried to find the limit, and created more of these loops. Particularly, I wasn't sure whether the loop variables in this case also count als "locals", because they are in their own { block }
. But still, more than 65534 is not possible. Finally, I added a test consisting of 40000 loops of the pattern
for (int i39999 = 0; i39999 < 10; i39999++) { int j = 0; Console.WriteLine(j + i39999); }
that contained an additional variable in the loop, but these seem to count as "locals" as well, and it was not possible to compile this.
So to summarize: The limit of ~550 is indeed caused by the nesting depth of the loops. This also was indicated by the error message
error CS8078: An expression is too long or complex to compile
The documentation of error CS1647 unfortunately (but understandably) does not specify a "measurement" of complexity, but only gives the pragmatic advice
There was a stack overflow in the compiler processing your code. To resolve this error, simplify your code.
To emphasize this again: For the particular case of deeply nested for
-loops, all this is rather academic and hypothetical. But websearching for the error message of CS1647 reveals several cases where this error appeared for code that was most likely not intentionally complex, but created in realistic scenarios.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With