top | item 47086163

(no title)

t43562 | 11 days ago

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.

discuss

order

vasama|11 days ago

> 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.

vbezhenar|11 days ago

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

t43562|11 days ago

You're right that it's not needed in my example but sometimes the thing that you're freeing has pointers inside it which themselves have to be freed first and in that case you need the if.

There are several other issues I haven't shown like what happens if you need to free something only when the return code is "FALSE" indicating that something failed.

This is not as nice as defer but up till now it was a comparatively nice way to deal with those functions which were really large and complicated and had many exit points.

jagged-chisel|11 days ago

But it does keep one in the habit of using NULL checks.

baq|11 days ago

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

Joker_vD|11 days ago

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

pocksuppet|11 days ago

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.

t43562|11 days ago

In your cleanup method you have to take the same care of parameters that you are putting results into as any other way you can deal with this. All it does is save you from repeating such logic at all the exit points.

bytejanitor|11 days ago

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

spiffyk|11 days ago

You don't. Labels are local to functions in C.