Me arriesgaré publicando esto, pero creo que la respuesta es:
Entre 550 y 575
con la configuración predeterminada en Visual Studio 2015
Creé un pequeño programa que genera for
bucles anidados ...
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);
}
}
...
...
}
}
Para 500 bucles anidados, el programa aún se puede compilar. Con 575 bucles, el compilador rescata:
Advertencia AD0001 Analyzer 'Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames.CSharpSimplifyTypeNamesDiagnosticAnalyzer' arrojó una excepción de tipo 'System.InsufficientExecutionStackException' con el mensaje 'Pila insuficiente para continuar ejecutando el programa de forma segura. Esto puede suceder por tener demasiadas funciones en la pila de llamadas o funciones en la pila que utilizan demasiado espacio en la pila. '.
con el mensaje del compilador subyacente
error CS8078: una expresión es demasiado larga o compleja para compilar
Por supuesto, este es un resultado puramente hipotético . Si el bucle más interno hace más de a Console.WriteLine
, es posible que haya menos bucles anidados antes de que se exceda el tamaño de la pila. Además, esto puede no ser un límite estrictamente técnico, en el sentido de que puede haber configuraciones ocultas para aumentar el tamaño máximo de pila para el "Analizador" que se menciona en el mensaje de error, o (si es necesario) para el ejecutable resultante. Esta parte de la respuesta, sin embargo, se deja a las personas que conocen C # en profundidad.
Actualizar
En respuesta a la pregunta en los comentarios :
Me interesaría ver esta respuesta expandida para "probar" experimentalmente si puede poner 575 variables locales en la pila si no se usan en bucles for, y / o si puede poner 575 bucles for no anidados en una sola función
Para ambos casos, la respuesta es: Sí, es posible. Al completar el método con 575 declaraciones generadas automáticamente
int i0=0;
Console.WriteLine(i0);
int i1=0;
Console.WriteLine(i1);
...
int i574=0;
Console.WriteLine(i574);
todavía se puede compilar. Todo lo demás me hubiera sorprendido. El tamaño de pila que se requiere para las int
variables es de solo 2,3 KB. Pero tenía curiosidad y, para probar otros límites, aumenté este número. Finalmente, no se compiló, lo que provocó el error
error CS0204: solo se permiten 65534 locales, incluidos los generados por el compilador
que es un punto interesante, pero ya se ha observado en otra parte: Número máximo de variables en el método
Del mismo modo, 575 bucles no anidados for
, como en
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);
}
también se puede compilar. Aquí, también intenté encontrar el límite y creé más de estos bucles. En particular, no estaba seguro de si las variables de bucle en este caso también cuentan como "locales", porque están en las suyas { block }
. Pero aún así, más de 65534 no es posible. Finalmente, agregué una prueba que consta de 40000 bucles del patrón
for (int i39999 = 0; i39999 < 10; i39999++)
{
int j = 0;
Console.WriteLine(j + i39999);
}
que contenía una variable adicional en el bucle, pero estos parecen contar también como "locales" y no fue posible compilar esto.
Entonces, para resumir: el límite de ~ 550 es causado por la profundidad de anidación de los bucles. Esto también fue indicado por el mensaje de error
error CS8078: una expresión es demasiado larga o compleja para compilar
La documentación del error CS1647 desafortunadamente (pero comprensiblemente) no especifica una "medida" de complejidad, sino que solo brinda consejos pragmáticos.
Hubo un desbordamiento de pila en el compilador procesando su código. Para resolver este error, simplifique su código.
Para enfatizar esto nuevamente: para el caso particular de for
bucles profundamente anidados , todo esto es bastante académico e hipotético . Pero la búsqueda web del mensaje de error de CS1647 revela varios casos en los que este error apareció para un código que probablemente no era intencionalmente complejo, sino que se creó en escenarios realistas.