Freigeben über


Zu viele nicht verschachtelte Schleifen führen in Visual C++ zu einem C1061-Compilerfehler.

Dieser Artikel hilft Ihnen, den C1061-Compilerfehler zu beheben, der auftritt, wenn Sie den Quellcode kompilieren, der mehr als 250 nicht geschachtelte Schleifen in einer Funktion enthält, die als C++-Quelldatei kompiliert wird.

Ursprüngliche Produktversion: Visual Studio Premium 2012, Visual Studio 2010
Ursprüngliche KB-Nummer: 315481

Symptome

Wenn eine Funktion mehr als 250 nicht geschachtelte Schleifen enthält, erhalten Sie die folgende Fehlermeldung, die in diesem Fall nicht angezeigt werden sollte.

Schwerwiegender Fehler C1061: Compilerlimit: Blöcke, die zu tief geschachtelt sind

Das Problem tritt nur auf, wenn Sie den Quellcode als C++-Quelldatei kompilieren. Der Quellcode kompiliert ohne Fehler, wenn Sie ihn als C-Quelldatei kompilieren.

Zwischenlösung

Schließen Sie jede Schleife in geschweifte Klammern ein, um einen eingeschlossenen Bereich zu erstellen:

{
    for (i=0; i<5; i++)
    {
        a += a*i;
    }
}

Schritte zum Reproduzieren des Verhaltens

Der folgende Beispielcode veranschaulicht den Fehler:

/* 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();
}

Mehr Informationen

Der C++-Compiler muss alle For-Loops im selben Bereich nachverfolgen, um die Warnung C4258 auszustellen, wenn /Zc:forScope aktiviert ist:

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
}

Wenn /Zc:ForScope deaktiviert ist, würde das i in der kommentierten Zeile stattdessen aus der For-Schleife stammen. Benutzer müssen über diesen Unterschied im Verhalten informiert werden.

Leider sind Bereiche nicht triviale Datenstrukturen, sodass der Compiler eine Beschränkung auf die Anzahl der Bereiche hat, die er gleichzeitig nachverfolgen kann, was zu dem hier beschriebenen Fehler führt.

Die Problemumgehung löst dieses Problem durch die Isolierung der einzelnen for-Schleifen, sodass sie nicht mehr im gleichen Scope wie andere for-Schleifen liegen, wodurch der Compiler nicht mehr die Notwendigkeit hat, alle Bereiche gleichzeitig nachzuverfolgen. Eine andere Möglichkeit, die Problemumgehung zu betrachten, besteht darin, dass sie verhindert, dass die Warnung C4258 außerhalb eines zusätzlichen eingeschlossenen Bereichs auftritt.

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
}