On Saturday 23 October 2004 7:46 pm, Yin Ming wrote: > AFAIK, one is jumping out of complex loops.
Another example:
I use gotos occasionally for cleaning up and error handling. Example:
(excuse the poor coding style. I never write my ifs this way - one liners and
with no brackets - in production code, but I am just trying to save space
here.)
int some_func()
{
void* v1;
void* v2;
void* v3;
int ret = 0;
v1 = get_some_resource();
if(v == NULL) return ret;
v2 = get_some_resource();
if(v2 == NULL) goto cleanup_v1;
v3 = get_some_resource();
if(v3 == NULL) goto_cleanup_v2;
if(!do_something(v1, v2, v3)) goto cleanup_v3;
if(!do_something(v1, v2, v3)) goto cleanup_v3;
ret = do_something_else(v1, v2, v3);
cleanup_v3:
release_resource(v3);
cleanup_v2:
release_resource(v2);
cleanup_v1:
release_resource(v1);
return ret;
}
If you have to allocate more than just a few resources, and you keep your
functions relatively small, I think that this approach actually helps
readability a bit. Is it possible to do without the goto? Absolutely. You
could include the clean up code in every if. You could write a special
function that checked the validity of each resource and then cleaned up only
the valid ones. Hell, I once knew a guy who used to recommend using a
do-while loop hack to emulate the same code but avoid the goto:
do {
v1 = ...
if(v1 == NULL) break;
do {
v2 = ...
if(v2 == NULL) break;
do {
v3 = ...
if(v3 == NULL) break;
if(!do_something(v1, v2, v3) break;
if(!do_something(v1, v2, v3) break;
ret = do_something_else(v1, v2, v3);
release_resource(v3);
} while(0);
release_resource(v2);
} while(0);
release_resource(v1);
} while(0);
return ret;
Personally, I find the goto method the easiest to code and maintain - at least
in the cases where you need to correctly allocate and release a fair number
of resources. It's MUCH easier to maintain than the do-while mess!
I would stress that this really should only be used in special circumstances
not as a general idiom for error handling, but on occasion it is useful.
Another note: NEVER do this in C++. Correctly using the RAII idiom should
completely eliminate the need for code like this with the added bonus of
making your code exception safe.
Josh
pgp1rfbARNGB7.pgp
Description: PGP signature
