On 2/6/13 14:14, Ralph Giles wrote:
On 13-02-06 10:45 AM, Timothy B. Terriberry wrote:

You can argue about whether or not that's any cleaner than using goto,
and I wouldn't insist that you don't, but at least this makes it clear
that you can't get out of do_something() without cleaning up your
resources (in this particular example), yet doesn't require code
duplication or macros.
Sure. The case I was thinking about involves 12 do_something functions,
but it does work.

You can also turn things inside out by using a wrapper for error
handling, at least when you have a context rather that purely local
allocations, as is generally the case in the webvtt code:

cleanup(ctx *self, int status) {
   if( status == OUT_OF_MEMORY ) {
     cleanup_stack(self);
   }
   reset_state(self);
   // Other cleanup...
   return status;
}

do_something(ctx *self, input *bar) {
   setup_state( self, bar );
   switch( bar->foo ) {
     case THING_A:
       ret = handle_a( self, bar );
       if( ret )
         return cleanup( self, ret );
       break;
     case THING_B:
       ptr = handle_b( self, bar ):
       if( ptr == NULL )
          return cleanup( self, OUT_OF_MEMORY );
   ...
   return SUCCESS;
}


That becomes tricky in the general case, where you have certain operations to be performed as part of all cleanup, and others performed only as part of error handling cleanup. The wrapper approach suffers this same shortcoming.

In the absence of exceptions, the judicious use of goto for error handling conditions is, IMHO, perfectly fine. There might be alternatives that fit the situation better, and those decisions can be made on a per-instance basis; but treating "goto" as a strictly verboten four-letter word removes a useful tool from the programmers' toolbox.

--
Adam Roach
Principal Platform Engineer
[email protected]
+1 650 903 0800 x863
_______________________________________________
dev-media mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-media

Reply via email to