4

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

3 回答 3

5

我假设使用 gcc(以及扩展 g++)默认的最大模板递归深度500至少在我的机器上我设法通过(稍微更好的)警告消息重现了您的问题。编译loop<500>::sum工作正常,但尝试编译loop<501>::sum失败。

如果您使用 gcc(或 g++),解决方案是使用-ftemplate-depth-##(其中 ## 是允许的最大深度)编译它。

因此,例如以main.cpp2000 的最大模板递归深度进行编译

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。代码本身是有效的,编译器甚至可以在一定数量的递归实例化后停止编译,给出诊断。但是,内部编译器错误(通俗地称为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 回答