Demasiados bucles sin inicializar provocan incorrectamente un error del compilador C1061 en Visual C++
Este artículo le ayuda a resolver el error del compilador C1061 que se produce al compilar el código fuente que incluye más de 250 bucles sin inicializar en una función como un archivo de origen de C++.
Versión original del producto: Visual Studio Premium 2012, Visual Studio 2010
Número de KB original: 315481
Síntomas
Si una función contiene más de 250 bucles sin inicializar aproximadamente, recibirá el siguiente mensaje de error, que no debería aparecer en este escenario:
error irrecuperable C1061: límite del compilador: bloques anidados demasiado
El problema solo se produce cuando se compila el código fuente como un archivo de código fuente de C++. El código fuente se compila sin errores al compilarlo como un archivo de origen de C.
Solución alternativa
Rodea cada bucle for con llaves para crear un ámbito envolvente:
{
for (i=0; i<5; i++)
{
a += a*i;
}
}
Pasos para reproducir el comportamiento
El código de ejemplo siguiente muestra el error:
/* Compile options needed: /TP /c
*/
#include <stdio.h>
// The code blocks in this function have only two nesting levels.
// C1061 should not occur.
void func1()
{
int a;
int i = 0;
int count = 0;
count++;
a = count;
for (i=0; i<5; i++)
{
a += a*i;
}
printf("a=%d\n", a);
// Copy and paste the following code 250 times.
/*
for (i=0; i<5; i++)
{
a += a*i;
}
printf("a=%d\n", a);
*/
count++;
a = count;
for (i=0; i<5; i++)
{
a += a*i;
}
printf("a=%d\n", a);
}
void main()
{
func1();
}
Más información
El compilador de C++ debe realizar un seguimiento de todos los bucles for en el mismo ámbito para emitir la advertencia C4258 cuando /Zc:forScope está habilitado:
int i;
void foo()
{
for (int i = 0; i < 10; ++i)
{
if (i == 5) break;
}
if (i == 5)... // C4258: this 'i' comes from an outer scope, not the for-loop
}
Con /Zc:ForScope deshabilitado, eso i en la línea comentada procedería del bucle for en su lugar. Se debe informar a los usuarios de esta diferencia de comportamiento.
Desafortunadamente, los ámbitos son estructuras de datos no triviales, por lo que el compilador tiene un límite en el número de ámbitos de los que puede realizar un seguimiento al mismo tiempo, lo que conduce al error descrito aquí.
La solución alternativa resuelve este problema mediante el aislamiento de cada bucle for para que ya no esté en el mismo ámbito que otros bucles for, lo que elimina la necesidad del compilador de realizar un seguimiento de todos sus ámbitos al mismo tiempo. Otra manera de examinar la solución alternativa es que evita la posibilidad de encontrar la advertencia C4258 fuera de un ámbito de inclusión adicional:
int i;
void foo()
{
{
for (int i = 0; i < 10; ++i)
{
if (i == 5) break;
}
}
if (i == 5)...
// this 'i' comes from the outer scope regardless of whether /Zc:forScope is enabled
}