4

私は初心者向けの構文と、VS2008 でこの短いコードを作成していたときにどのように機能するかを学ぼうとしていました。以下のコードは、1 から 499 までの数字を加算するのに機能しますが、1 から 500 までを加算すると、コンパイラがバグを出して次のように表示します。

fatal error C1001: An internal error has occurred in the compiler.

そして、私はそれがなぜだろうと思っていました。コンパイラが生成できるコードの量に制限はありますか?

#include <iostream>
using namespace std;

template < int b >
struct loop {
    enum { sum = loop< b - 1 >::sum + b };
};

template <>
struct loop< 0 > {
    enum { sum = 0 };
};

int main() {
    cout << "Adding the numbers from 1 to 499 = " << loop< 499 >::sum << endl;
    return 0;
}
4

3 に答える 3

5

gcc (および拡張 g++) を使用すると、デフォルトの最大テンプレート再帰深度は500、少なくとも私のマシンでは (わずかに良い) 警告メッセージで問題を再現できたと思います。コンパイルloop<500>::sumはうまくいきましたが、コンパイルしようとしてloop<501>::sum失敗しました。

gcc (または g++) を使用している場合、解決策はコンパイルすることです-ftemplate-depth-##(## は最大許容深さです)。

たとえばmain.cpp、最大テンプレート再帰深度 2000 でコンパイルするには

g++ -ftemplate-depth-2000 main.cpp

または、コードを次のように変換します。

template < int b >
struct loop {
    enum { sum = (b*(b+1))/2 };
};

(しかし、上記のコードがテンプレートのメタプログラミングについて学ぶのに役立たないことは認めます)

于 2010-04-14T15:04:17.313 に答える
5

VC9 (VS2008) は 499 を超える数値でクラッシュします。コード自体は有効であり、コンパイラは再帰的なインスタンス化を一定量行った後にコンパイルを停止することも許可されており、診断が行われます。ただし、Internal Compiler Error (口語的にICEとも呼ばれます) は確かに適切な診断ではありません。

ICE は常にコンパイラのエラーです。コード内のエラーが原因である可能性もありますが、その場合、コンパイラはそのエラーの適切な診断を表示できませんでした。エラーが再現可能な場合は、バグ レポートをコンパイラ ベンダーに送信して、エラーを修正できるようにする必要があります。

このようなエラーを (ここまたは他の場所で) 報告するときは、使用した正確なコンパイラ バージョンを必ず提供してください。

于 2010-04-14T15:05:52.380 に答える
2

出力ウィンドウを見てください。

c:\ projects \ cpptemp3 \ cpptemp3.cpp(9):
致命的なエラーC1001:コンパイラで内部エラーが発生しました。(コンパイラファイル'msc1.cpp'、行1411) この問題を回避するには、上記の場所の近くでプログラムを単純化または変更してみてください。

于 2010-04-14T15:20:12.383 に答える