未承認ループが多すぎると、Visual C++ で C1061 コンパイラ エラーが発生する
この記事は、C++ ソース ファイルとして関数に 250 を超える未更新ループを含むソース コードをコンパイルするときに発生する 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();
}
詳細
/Zc:forScope が有効になっているときに警告 C4258 を発行するには、C++ コンパイラが同じスコープ内のすべての for ループを追跡する必要があります。
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 ループから取得されます。 この動作の違いをユーザーに通知する必要があります。
残念ながら、スコープは単純ではないデータ構造であるため、コンパイラは同時に追跡できるスコープの数に制限があるため、ここで説明するバグが発生します。
この回避策では、各 for ループを分離して、他の for ループと同じスコープにならないようにすることでこの問題を解決します。これにより、コンパイラのすべてのスコープを同時に追跡する必要がなくなります。 回避策を見るもう 1 つの方法は、余分な囲みスコープ外で警告 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
}
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示