¿Por qué este código tarda tanto en compilarse con g ++?

12

Considere el siguiente código:

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

Al comparar su compilación por g ++ con el siguiente 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

Me sale el siguiente resultado:

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

Entonces, el tiempo de compilación es exponencial en LEVEL. Pero si cambio B x, y;a B x[2];, entonces la compilación ocurre en tiempo constante (~ 30 ms).

¿Por que sucede? Pensé que, dado que el compilador sabe que Bes uno y el mismo tipo para ambos xy y, tomaría el mismo tiempo que compilar x[2]. Pero por alguna razón parece diferente. ¿De alguna manera puedo forzar Bque se realice (en lugar de simplemente alias) para que g ++ pueda crear ambas variables tan fácilmente como creó la matriz?

Ruslan
fuente
1
Una respuesta técnicamente correcta pero inútil (para ti): parchea el compilador.
Botje
55
¿Por qué publicas eso aquí? Gcc tiene un bugzilla para informar problemas ... Sin embargo, asegúrese de probar primero con la última versión.
Marc Glisse
@MarcGlisse Esperaba que pudiera haber una buena explicación o una solución alternativa. No estoy seguro de si se consideraría un error que vale la pena intentar solucionar si lo denunciara como tal.
Ruslan
3
Incluso tienen una palabra clave "compile-time-hog" para los casos en que el compilador tarda demasiado en compilarse, por lo que sí consideran que vale la pena arreglarlo (lo que no significa que lo harán de inmediato). Entonces, especialmente si puede ver otro compilador que no tiene el comportamiento exponencial (para que sepa que es evitable), por favor repórtelo. Bueno, tal vez verifique si ve algo muy similar en la base de datos, pero está bien si pierde un duplicado no obvio.
Marc Glisse el
55
@MarcGlisse informó: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Ruslan

Respuestas:

1

Porque hay un error en tu instancia de g ++. No debería, y como comentó @Marc Glisse, debe informarlo (lo que había hecho al momento de escribir)

Es posible que desee eliminar su pregunta entonces (opción más sabia). O acepta esta respuesta.

Heyji
fuente