Still seems like a needless use of goto.<p><pre><code>    struct resources {
        resourceA *a;
        resourceB *b;
        resourceC *c;
    };
    
    int init(resources *r) {
        err = funA(r-&gt;a);
        if (err)
            {cleanup(r); return err;}
        
        err = funB(r-&gt;b);
        if (err)
            {cleanup(r); return err;}
        
        err = funC(r-&gt;c);
        if (err)
            {cleanup(r); return err;}
        
        return 0;
    }
    
    void cleanup(resources *r) {
        if (r-&gt;a)
            {specialFree(r-&gt;a);}
        
        if (r-&gt;b)
            {specialFree(r-&gt;b);}
        
        if (r-&gt;c)
            {specialFree(r-&gt;c);}
        
        free r;
     }
</code></pre>
And this has the added benefit of being more structured, more testable.  The same cleanup() code can be used for normal cleanup as well as error handling, so you have less duplication.