Просто представился TMPing и натолкнулся на причуду - PullRequest
4 голосов
/ 14 апреля 2010

Я просто пытался изучить синтаксис новичков и то, как он работал, когда я делал этот короткий кусочек кода в 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 ]

5 голосов
/ 14 апреля 2010

VC9 (VS2008) аварийно завершает работу с числами> 499. Сам код действителен, и компиляторам даже разрешено останавливать компиляцию после определенного количества рекурсивных реализаций, предоставляя диагностику. Тем не менее, Внутренняя ошибка компилятора (в разговорной речи также называется ICE ) определенно не является хорошей диагностикой.

ICE всегда является ошибкой компилятора. Это также может быть вызвано ошибкой в ​​коде, но если это так, то компилятору не удалось показать правильную диагностику для этой ошибки. Если ошибка воспроизводима, вы должны отправить отчет об ошибке поставщику компилятора, чтобы он мог исправить свою ошибку.

При сообщении о такой ошибке (здесь или где-либо еще) вы никогда не должны указывать точную версию компилятора, которую вы использовали.

5 голосов
/ 14 апреля 2010

Я предполагаю, что с 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 };
};

(но я признаю, что приведенный выше код не поможет вам узнать о метапрограммировании шаблонов)

2 голосов
/ 14 апреля 2010

Посмотрите в окне вывода:

C: \ Проекты \ cpptemp3 \ cpptemp3.cpp (9):
фатальная ошибка C1001: внутренняя ошибка произошло в компиляторе. (файл компилятора 'msc1.cpp', строка 1411) Чтобы обойти эту проблему, попробуйте упростить или изменить программу возле мест, перечисленных выше.

...