TMPing について自己紹介をしたところ、奇妙なことに気づきました
-
26-09-2019 - |
質問
私は、VS2008 でこの短いコードを作成していたときに、初心者向けの構文とそれがどのように機能するかを学ぼうとしていたところです。以下のコードは、1 から 499 までの数値を加算する際に機能しますが、1 から 500 まで加算すると、コンパイラがバグって次のように表示します。
fatal error C1001: An internal error has occurred in the compiler.
そして、それはなぜなのか疑問に思っていました。コンパイラーが生成できるコードの量に何らかの制限があるのか、それとも何かで、たまたまそれが私にとってちょうど良い概数の 500 だっただけでしょうか?
#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;
}
解決
私は(わずかに良い)警告メッセージを表示してあなたの問題を再現するために管理私のマシン上に、少なくともとしてgccで(および拡張G ++で)デフォルトの最大テンプレート再帰の深さが500
であると仮定します。 loop<500>::sum
をコンパイルすると、罰金を働いたがloop<501>::sum
をコンパイルしようとすると、失敗します。
gccを使用している場合(またはg ++)溶液(##が最大許容深さである。)-ftemplate-depth-##
でそれをコンパイルすることです。
そこで、例えば2000の最大テンプレート再帰の深さmain.cpp
をコンパイルするために
g++ -ftemplate-depth-2000 main.cpp
またはこれにコードを変換します:
template < int b >
struct loop {
enum { sum = (b*(b+1))/2 };
};
(しかし、私は上記のコードを使用すると、テンプレートメタプログラミングについて学ぶ助けにはならない認めるだろう)
他のヒント
はVC9(VS2008)コード自体番号> 499でクラッシュが有効であり、コンパイラであっても診断を与え、再帰インスタンスの一定量の後に停止編集を許可されています。しかし、の内部コンパイラエラーの(口語的とも呼ばれるのICEは、の)確かに素敵な診断ではありません。
ICEは常に、コンパイラのエラーです。それはあまりにも、コードのエラーが原因である可能性がありますが、そのような場合、コンパイラはそのエラーのための適切な診断を示すことができませんでした。エラーが再現可能である場合は、コンパイラベンダーにバグレポートを提出しなければならないので、彼らは自分のエラーを修正することができます。
(ここでまたは他の場所)このようなエラーを報告する場合は、あなたが使用される正確なコンパイラのバージョンを提供することができないことはありません。
出力ウィンドウを見てください。
c:\projects\cpptemp3\cpptemp3.cpp(9):
致命的なエラー C1001:内部エラー がコンパイラで発生しました。(コンパイラ ファイル「msc1.cpp」、1411 行目) この問題を回避するには、上記の場所の近くのプログラムを簡素化または変更してみてください。