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

Attachment: pgp1rfbARNGB7.pgp
Description: PGP signature

Reply via email to