Чому цей код займає стільки часу, щоб компілювати з 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
Технічно правильна, але марна (для вас) відповідь: виправте компілятор.
Ботє

5
Чому ви це публікуєте тут? У Gcc є багзілла для повідомлення про проблеми ... Не забудьте спробувати спочатку останню версію.
Марк

@MarcGlisse Я сподівався, що це може бути хорошим поясненням або рішенням. Не впевнений, чи вважатиметься помилка, яку варто спробувати виправити, якби я повідомив про неї як таку.
Руслан

3
У них навіть є ключове слово «компіляція-час-свиня» для тих випадків, коли компілятор займає занадто багато часу для компіляції, тому так, вони вважають, що це варто виправити (це не означає, що вони зроблять це негайно). Отже, особливо якщо ви бачите іншого компілятора, який не має експоненціальної поведінки (так що ви знаєте, що це можна уникнути), будь ласка, повідомте про це. Можливо, перевірте, чи бачите ви щось схоже в базі даних, але це нормально, якщо ви пропустите неочевидний дублікат.
Марк

5
@MarcGlisse повідомив: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Руслан

Відповіді:


1

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

Ви можете потім видалити своє запитання (мудріший вибір). Або прийміть цю відповідь.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.