3 ms·
Still seems like a needless use of goto. struct resources { resourceA *a; resourceB *b; resourceC *c; }; int init(reso
by keenerd 11y ago
Still seems like a needless use of goto.
struct resources {
resourceA *a;
resourceB *b;
resourceC *c;
};
int init(resources *r) {
err = funA(r->a);
if (err)
{cleanup(r); return err;}
err = funB(r->b);
if (err)
{cleanup(r); return err;}
err = funC(r->c);
if (err)
{cleanup(r); return err;}
return 0;
}
void cleanup(resources *r) {
if (r->a)
{specialFree(r->a);}
if (r->b)
{specialFree(r->b);}
if (r->c)
{specialFree(r->c);}
free r;
}
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.
- marcoperaza 11y agoThis doesn't have any advantages over the goto version. So now you're defining a struct and a special cleanup function for every function that you write. And in the name of what? A religious avoidance of goto?
- Gibbon1 11y ago> A religious avoidance of goto? That's my experience. In school the no goto rule is exactly like your second grade teacher telling you never to start a sentence with the word 'and' It's to prevent this; And we went to the park. And I played on the swing And then we went and got ice cream. And we went home and had dinner. The no goto rule is for novices to teach them not to write spaghetti code.