Quais são algumas boas maneiras de lidar com erros (limpeza e interrupção) em uma função que inicializa vários recursos em C?

Primeiro de tudo, se alguém puder reformular a pergunta para torná-la mais clara, faça isso.

Uma ocorrência comum na programação C está tendo vários recursos para serem inicializados / alocados em uma ordem específica. Cada recurso é um pré-requisito para a inicialização dos subsequentes. Se uma das etapas falhar, os recursos restantes das etapas anteriores deverão ser desalocados. O pseudocódigo ideal (utilizando uma função puramente unobtainium clean_up_and_abort () magicamente genérica) ficaria aproximadamente da seguinte maneira:

err=alloc_a()
if(err)
    clean_up_and_abort()

err=alloc_b()
if(err)
    clean_up_and_abort()

err=alloc_c()
if(err)
    clean_up_and_abort()

// ...

profit()

Eu já vi várias maneiras de lidar com isso, todas elas parecem ter desvantagens significativas, pelo menos em termos do que as pessoas tendem a considerar "boas práticas".

Quais são as formas mais legíveis e menos propensas a erros de estruturar o código ao lidar com essa situação? A eficiência é preferida, mas uma quantidade razoável de eficiência pode ser sacrificada em prol da legibilidade. Por favor, liste vantagens e desvantagens. Respostas discutindo vários métodos são bem-vindas.

Esperamos que o objetivo seja terminar com um conjunto de vários métodos preferidos para resolver esse problema.

Vou começar com alguns dos métodos que eu já vi,comente-os e adicione outros.

questionAnswers(2)

yourAnswerToTheQuestion