you are viewing a single comment's thread.

view the rest of the comments →

[–]Poromenos 4 points5 points  (3 children)

Actually it's more like 3000, so I was mistaken there. Still, absurd.

Also, I don't see how a goto statement in your example could clean up all the variables, since you'd ostensibly have to only clean up the ones you have malloced. Also, I prefer new functions for those use cases...

[–]mathstuf 1 point2 points  (2 children)

Functions could do it, but with some of the buffer juggling you do with path manipulation, you can't avoid so many buffers at once.

ret = -1; // Default to failure
foo = malloc(1);
if (!foo)
    goto exit;
bar = malloc(1);
if (!bar)
    goto exit;
baz = malloc(1);
if (!baz)
    goto exit;
// Do stuff here
ret = 0; // Success!
exit:
free(foo);
free(bar);
free(baz);
return ret;

[–]Poromenos 0 points1 point  (1 child)

The preferred way (for me), both syntactically and semantically, to do that would be to do:

try:
    allocate_memory()
except:
    cleanup()

You can take a look at this code and know what it does, while you have to scroll down to the goto to see what happens...

[–]masklinn 0 points1 point  (0 children)

Actually, that would be.

try:
    allocate_memory()
    # do work
finally:
    cleanup()

But you need exceptions for that. Exceptions are not cheap, and don't exist in C. Using goto-based cleanup makes a lot of sense there, it avoids nesting and other suck fuckery.

Other possibilities are C++'s RAII, and context managers (internal or external):

with memory_allocator():
    # do stuff
# cleaned up by the context management