Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a limit to the number of nested 'for' loops?

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....       }     }   } } 
like image 608
Fred Smith Avatar asked Dec 27 '16 14:12

Fred Smith


People also ask

Is there such thing as too many nested loops?

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.

Is there a limit to nested for loops python?

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).

Is there limit to nested loops Java?

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.

How many times nested loops run?

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)…..


1 Answers

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.


Update

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.

like image 73
Marco13 Avatar answered Sep 28 '22 02:09

Marco13