Почему этот код так долго компилируется с g ++?

12

Рассмотрим следующий код:

template<int i> class A
{
    typedef A<i-1> B;
    B x, y;
};
template<> class A<0> { char m; };
int main()
{
    A<LEVEL> a;
}

При тестировании его компиляции с помощью g ++ с помощью следующей команды Bash (с g ++ 8.3.0)

for ((level=1; level<30; ++level)); do
    echo -n ${level},
    /usr/bin/time -f %U g++ -DLEVEL=$level test.cpp -o /dev/null
done

Я получаю следующий вывод:

1,0.03
2,0.03
3,0.04
4,0.04
5,0.04
6,0.04
7,0.04
8,0.04
9,0.03
10,0.04
11,0.02
12,0.04
13,0.02
14,0.03
15,0.04
16,0.05
17,0.05
18,0.08
19,0.11
20,0.20
21,0.35
22,0.67
23,1.30
24,2.52
25,5.02
26,10.23
27,19.96
28,40.30
29,80.99

Таким образом, время компиляции экспоненциально в LEVEL. Но если я перехожу B x, y;на B x[2];, то компиляция происходит за постоянное время (~ 30 мс).

Почему это происходит? Я думал, что, так как компилятор знает, что Bэто один и тот же тип для обоих, xи yэто займет то же время, что и компиляция x[2]. Но почему-то это выглядит иначе. Можно ли как-то заставить Bреализоваться (в отличие от просто псевдонима), чтобы g ++ мог создавать обе переменные так же легко, как и массив?

Руслан
источник
1
Технически правильный, но бесполезный (для вас) ответ: исправьте компилятор.
Botje
5
Зачем вы публикуете это здесь? Gcc имеет bugzilla для сообщения о проблемах ... Убедитесь, что вы сначала протестировали последнюю версию.
Марк
@MarcGlisse Я надеялся, что может быть хорошее объяснение или обходной путь. Не уверен, что это будет ошибкой, если я сообщу об этом.
Руслан
3
У них даже есть ключевое слово "compile-time-hog" для случаев, когда компилятору требуется слишком много времени для компиляции, так что да, они считают, что это стоит исправить (что не означает, что они сделают это немедленно). Поэтому, особенно если вы видите другой компилятор, который не имеет экспоненциального поведения (так что вы знаете, что его можно избежать), сообщите об этом. Ну, возможно, проверьте, видите ли вы что-то очень похожее в базе данных, но это нормально, если вы пропустите неочевидный дубликат.
Марк
5
@MarcGlisse сообщил: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Руслан

Ответы:

1

Потому что в вашем экземпляре g ++ есть ошибка. Он не должен, и, как прокомментировал @Marc Glisse, вы должны сообщить об этом (что вы сделали на момент написания)

Тогда вы можете удалить свой вопрос (более разумный выбор). Или примите этот ответ.

Heyji
источник