Pourquoi ce code prend-il autant de temps à compiler avec g ++?

12

Considérez le code suivant:

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

Lors de l'analyse comparative de sa compilation par g ++ par la commande Bash suivante (avec 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

J'obtiens la sortie suivante:

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

Ainsi, le temps de compilation est exponentiel LEVEL. Mais si je passe B x, y;à B x[2];, la compilation se fait en temps constant (~ 30 ms).

Pourquoi cela arrive-t-il? Je pensais que, puisque le compilateur sait que Bc'est un seul et même type pour les deux xet y, cela prendrait le même temps que la compilation x[2]. Mais pour une raison quelconque, cela semble différent. Puis-je en quelque sorte forcer Bà être réalisé (par opposition à simplement aliasé) afin que g ++ puisse créer les deux variables aussi facilement qu'il a créé le tableau?

Ruslan
la source
1
Une réponse techniquement correcte mais inutile (pour vous): corrigez le compilateur.
Botje
5
Pourquoi publieriez-vous cela ici? Gcc a un bugzilla pour signaler les problèmes ... Assurez-vous de tester d'abord avec la dernière version.
Marc Glisse
@MarcGlisse J'espérais qu'il pourrait y avoir une bonne explication ou une solution de contournement. Je ne sais pas si cela serait considéré comme un bug à essayer de corriger si je le signalais comme tel.
Ruslan
3
Ils ont même un mot clé "compile-time-hog" pour les cas où le compilateur prend trop de temps à compiler, alors oui, ils considèrent qu'il vaut la peine d'être corrigé (ce qui ne signifie pas qu'ils le feront immédiatement). Donc, surtout si vous pouvez voir un autre compilateur qui n'a pas le comportement exponentiel (donc vous savez qu'il est évitable), veuillez le signaler. Eh bien, vérifiez peut-être si vous voyez quelque chose de très similaire dans la base de données, mais c'est correct si vous manquez un doublon non évident.
Marc Glisse
5
@MarcGlisse a signalé: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Ruslan

Réponses:

1

Parce qu'il y a un bogue dans votre instance g ++. Cela ne devrait pas, et comme l'a commenté @Marc Glisse, vous devez le signaler (ce que vous avez fait au moment de la rédaction)

Vous voudrez peut-être alors supprimer votre question (choix plus sage). Ou acceptez cette réponse.

Heyji
la source