只是向TMPing介绍自己,并遇到了一个怪癖

时间:2010-04-14 14:55:33

标签: c++ templates metaprogramming c1001

我只是想学习初学者的语法,以及当我在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;
}

3 个答案:

答案 0 :(得分: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 };
};

(但我承认上面的代码无法帮助您了解模板元编程)

答案 1 :(得分:5)

VC9(VS2008)与数字&gt;崩溃499.代码本身是有效的,甚至允许编译器在一定量的递归实例化之后停止编译,从而进行诊断。但是,内部编译器错误(通俗地也称为 ICE )当然不是一个很好的诊断。

ICE始终是编译器的错误。它也可能是由代码中的错误引起的,但如果是这种情况,则编译器无法显示该错误的正确诊断。如果错误是可重现的,您应该向编译器供应商提交错误报告,以便他们可以修复错误。

报告此类错误(此处或其他地方)时,您应该永远不会提供您使用的确切编译器版本。

答案 2 :(得分:2)

查看“输出”窗口:

  

C:\项目\ cpptemp3 \ cpptemp3.cpp(9):
  致命错误C1001:内部错误   在编译器中发生过。       (编译器文件'msc1.cpp',第1411行)       要解决此问题,请尝试简化或更改程序   靠近上面列出的位置。