Perché questo codice impiega così tanto tempo per essere compilato con g ++?


12

Considera il seguente codice:

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

Quando si confronta la sua compilazione con g ++ con il seguente comando Bash (con 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

Ottengo il seguente output:

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

Quindi, il tempo di compilazione è esponenziale in LEVEL. Ma se cambio B x, y;a B x[2];, la compilazione avviene in tempo costante (~ 30 ms).

Perché succede? Ho pensato che, poiché il compilatore sa che Bè lo stesso tipo per entrambi xe y, ci vorrebbe lo stesso tempo della compilazione x[2]. Ma per qualche motivo sembra diverso. Posso in qualche modo forzare la Brealizzazione (al contrario del semplice aliasing) in modo che g ++ possa creare entrambe le variabili con la stessa facilità con cui ha creato l'array?


1
Una risposta tecnicamente corretta ma inutile (per te): patch il compilatore.
Botje,

5
Perché lo pubblichi qui? Gcc ha una bugzilla per la segnalazione di problemi ... Assicurati però di provare prima con l'ultima versione.
Marc Glisse,

@MarcGlisse Speravo ci potesse essere una buona spiegazione o una soluzione alternativa. Non sono sicuro se sarebbe considerato un bug che vale la pena provare a risolvere se lo segnalassi come tale.
Ruslan,

3
Hanno anche una parola chiave "compile-time-hog" per i casi in cui il compilatore impiega troppo tempo per essere compilato, quindi sì, lo considerano degno di essere risolto (il che non significa che lo faranno immediatamente). Quindi, specialmente se riesci a vedere un altro compilatore che non ha un comportamento esponenziale (quindi sai che è evitabile), per favore segnalalo. Beh, forse controlla se vedi qualcosa di molto simile nel database, ma va bene se perdi un duplicato non ovvio.
Marc Glisse,

Risposte:


1

Perché c'è un bug nella tua istanza di g ++. Non dovrebbe, e come ha commentato @Marc Glisse, dovresti segnalarlo (cosa che hai fatto al momento della stesura)

Quindi potresti voler eliminare la tua domanda (scelta più saggia). O accetta questa risposta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.