Просто познакомился с 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-##
(Где ## - максимально допустимая глубина).
Так, например, для компиляции main.cpp
с максимальной глубиной рекурсии шаблона 2000 года
g++ -ftemplate-depth-2000 main.cpp
Или преобразуйте код к этому:
template < int b >
struct loop {
enum { sum = (b*(b+1))/2 };
};
(Но я признаю вышеуказанный код не поможет вам узнать о шаблоне MetaProgramming)
Другие советы
VC9 (VS2008) аварийно завершает работу с номерами > 499.Сам код действителен, и компиляторам даже разрешено останавливать компиляцию после определенного количества рекурсивных реализаций, выдавая диагностику.Тем не менее, Внутренняя ошибка компилятора (в просторечии также называется ЛЕД), конечно, не является хорошей диагностикой.
ICE — это всегда ошибка компилятора.Это также может быть вызвано ошибкой в коде, но в этом случае компилятор не смог предоставить правильную диагностику этой ошибки.Если ошибка воспроизводима, вам следует отправить отчет об ошибке поставщику компилятора, чтобы он мог исправить свою ошибку.
Сообщая о такой ошибке (здесь или где-либо еще), вы никогда не должны упускать из виду точную версию компилятора, которую вы использовали.
Посмотрите в выходное окно:
C: Projects CPPTEMP3 CPPTEMP3.cpp (9):
Фатальная ошибка C1001: в компиляторе произошла внутренняя ошибка. (файл компилятора 'msc1.cpp', линия 1411) Работать вокруг этой проблемы, попробуйте упростить или изменять программу рядом с указанным выше локациями.