Mengapa kode ini membutuhkan waktu lama untuk dikompilasi dengan g ++?

12

Pertimbangkan kode berikut:

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

Saat membandingkan kompilasi dengan g ++ dengan perintah Bash berikut (dengan 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

Saya mendapatkan output berikut:

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

Jadi, waktu kompilasi adalah eksponensial dalam LEVEL. Tapi jika saya mengubah B x, y;ke B x[2];, kemudian kompilasi terjadi dalam waktu yang konstan (~ 30 ms).

Mengapa itu terjadi? Saya pikir itu, karena kompiler tahu itu Badalah satu dan tipe yang sama untuk keduanya xdan y, itu akan membutuhkan waktu yang sama dengan kompilasi x[2]. Tetapi untuk beberapa alasan tampaknya berbeda. Bisakah saya memaksa Buntuk direalisasikan (sebagai lawan dari hanya alias) sehingga g ++ dapat membuat kedua variabel semudah menciptakan array?

Ruslan
sumber
1
Jawaban yang benar secara teknis tetapi tidak berguna (untuk Anda): tambal kompiler.
Botje
5
Mengapa Anda mempostingnya di sini? Gcc memiliki bugzilla untuk melaporkan masalah ... Pastikan Anda menguji dengan versi terbaru terlebih dahulu.
Marc Glisse
@MarcGlisse Saya berharap mungkin ada penjelasan atau solusi yang baik. Tidak yakin apakah itu akan dianggap sebagai bug yang layak untuk diperbaiki jika saya melaporkannya.
Ruslan
3
Mereka bahkan memiliki kata kunci "compile-time-hog" untuk kasus-kasus di mana kompiler membutuhkan waktu terlalu lama untuk dikompilasi, jadi ya mereka menganggap itu layak diperbaiki (yang tidak berarti mereka akan segera melakukannya). Jadi terutama jika Anda dapat melihat kompiler lain yang tidak memiliki perilaku eksponensial (sehingga Anda tahu itu dapat dihindari), tolong laporkan. Yah mungkin memeriksa jika Anda melihat sesuatu yang sangat mirip dalam database, tetapi tidak apa-apa jika Anda kehilangan duplikat yang tidak jelas.
Marc Glisse
5
@MarcGlisse melaporkan: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Ruslan

Jawaban:

1

Karena ada bug dalam instance g ++ Anda. Seharusnya tidak, dan seperti yang dikomentari @Marc Glisse, Anda harus melaporkannya (yang telah Anda lakukan pada saat penulisan)

Anda mungkin ingin menghapus pertanyaan Anda (pilihan lebih bijaksana). Atau terima jawaban ini.

Heyji
sumber