过多的未引入循环错误导致 Visual C++ 中的 C1061 编译器错误

本文可帮助你解决在函数中将包含超过 250 个未引入循环的源代码作为C++源文件时发生的 C1061 编译器错误。

原始产品版本: Visual Studio Premium 2012、Visual Studio 2010
原始 KB 数: 315481

现象

如果函数包含大约 250 个未引入的循环,则会收到以下错误消息,这种情况不应显示:

致命错误 C1061:编译器限制:块嵌套太深

仅当将源代码编译为C++源文件时,才会出现问题。 源代码在编译为 C 源文件时编译时不会出错。

解决方法

用大括号将每个 for 循环括起来,以创建封闭范围:

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

重现行为的步骤

以下示例代码演示了错误:

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

详细信息

C++编译器必须跟踪同一范围内的所有 for-loop,以便在启用 /Zc:forScope发出警告 C4258:

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
}

禁用 /Zc:ForScope 后, i 注释行上的该行将改为来自 for-loop。 用户必须了解此行为差异。

遗憾的是,范围是非普通数据结构,因此编译器对它可以同时跟踪的范围数量有限制,这会导致此处所述的 bug。

解决方法通过隔离每个 for-loop 来解决此问题,以便它不再与其他 for-loop 位于同一范围内,从而消除了编译器同时跟踪其所有范围的需求。 另一种查看解决方法的方法是,它避免在额外的封闭范围之外遇到警告 C4258 的可能性:

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
}