Considere a seguinte implementação de lista vinculada única:
struct node {
std::unique_ptr<node> next;
ComplicatedDestructorClass data;
}
Agora, suponha que eu pare de usar alguma std::unique_ptr<node> head
instância que fica fora do escopo, fazendo com que seu destruidor seja chamado.
Isso vai explodir minha pilha para listas suficientemente grandes? É justo supor que o compilador faça uma otimização bastante complicada ( unique_ptr
o destruidor do inline para o node
's' e depois use a recursão da cauda), o que fica muito mais difícil se eu fizer o seguinte (já que o data
destruidor ofuscaria next
o do, tornando difícil para o compilador perceber as possíveis oportunidades de reordenação e chamada final):
struct node {
std::shared_ptr<node> next;
ComplicatedDestructorClass data;
}
Se de data
alguma forma tem um ponteiro para node
isso, pode até ser impossível a recursão da cauda (embora, é claro, devamos nos esforçar para evitar tais violações do encapsulamento).
Em geral, como alguém deveria destruir essa lista, então? Não podemos percorrer a lista e excluir o nó "atual" porque o ponteiro compartilhado não possui um release
! A única maneira é com um deleter personalizado, que é realmente fedorento para mim.
gcc -O3
não foi possível otimizar uma recursão de cauda (em um exemplo complicado).