logoalt Hacker News

t43562today at 10:30 AM6 repliesview on HN

In C I just used goto - you put a cleanup section at the bottom of your code and your error handling just jumps to it.

  #define RETURN(x) result=x;goto CLEANUP

  void myfunc() {
    int result=0;
    if (commserror()) {
      RETURN(0);
    }
     .....
    /* On success */
    RETURN(1);

    CLEANUP:
    if (myStruct) { free(myStruct); }
    ...
    return result
  }
The advantage being that you never have to remember which things are to be freed at which particular error state. The style also avoids lots of nesting because it returns early. It's not as nice as having defer but it does help in larger functions.

Replies

vasamatoday at 10:56 AM

> The advantage being that you never have to remember which things are to be freed at which particular error state.

You also don't have to remember this when using defer. That's the point of defer - fire and forget.

vbezhenartoday at 10:41 AM

One small nitpick: you don't need check before `free` call, using `free(NULL)` is fine.

show 2 replies
baqtoday at 11:06 AM

defer is a stack, scope local and allows cleanup code to be optically close to initialization code.

Joker_vDtoday at 1:30 PM

The disadvantage is that a "goto fail" can easily happen with this approach. And it actually had happened in the wild.

pocksuppettoday at 11:29 AM

This looks like a recipe for disaster when you'll free something in the return path that shouldn't be freed because it's part of the function's result, or forget to free something in a success path. Just write

    result=x;
    goto cleanup;
if you meant

    result=x;
    goto cleanup;
At least then you'll be able to follow the control flow without remembering what the magic macro does.
show 1 reply
bytejanitortoday at 10:51 AM

But you have to give this cleanup jump label a different name for every function.

show 1 reply