Por que esse código leva tanto tempo para compilar com o g ++?

12

Considere o seguinte 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;
}

Ao comparar sua compilação por g ++ com o seguinte comando Bash (com 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

Eu recebo a seguinte saída:

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

Portanto, o tempo de compilação é exponencial em LEVEL. Mas se eu mudar B x, y;para B x[2];, a compilação acontece em tempo constante (~ 30 ms).

Por que isso acontece? Pensei que, já que o compilador sabe que Bé um eo mesmo tipo para ambos xe y, levaria ao mesmo tempo que a compilação x[2]. Mas, por alguma razão, parece diferente. De alguma forma, posso forçar Ba realização (em oposição a simplesmente alias), para que o g ++ possa criar as duas variáveis ​​tão facilmente quanto criou a matriz?

Ruslan
fonte
11
Uma resposta tecnicamente correta, mas inútil (para você): faça o patch do compilador.
Botje 4/10/19
5
Por que você postaria isso aqui? O Gcc tem um bugzilla para relatar problemas ... Certifique-se de testar primeiro a versão mais recente.
Marc Glisse
@ MarcGlisse Eu esperava que pudesse haver uma boa explicação ou uma solução alternativa. Não tenho certeza se seria considerado um bug que vale a pena tentar consertar se eu o denunciei como tal.
Ruslan
3
Eles até têm uma palavra-chave "tempo de compilação" para casos em que o compilador leva muito tempo para compilar; portanto, eles consideram que vale a pena consertar (o que não significa que eles façam isso imediatamente). Portanto, especialmente se você puder ver outro compilador que não possui comportamento exponencial (para que você saiba que é evitável), informe-o. Bem, talvez verifique se você vê algo muito semelhante no banco de dados, mas tudo bem se você perder uma duplicata não óbvia.
Marc Glisse
5
@MarcGlisse relatou: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Ruslan

Respostas:

1

Porque existe um erro na sua instância do g ++. Não deveria, e como @Marc Glisse comentou, você deve denunciá-lo (o que você fez no momento da redação)

Você pode excluir sua pergunta (escolha mais sábia). Ou aceite esta resposta.

Heyji
fonte