← Back to context

Comment by coherentpony

12 years ago

I don't see the difference between this and

    cleanup(state);
    error(state);

etc.

Just pull them each out into a function. You're still DRY and don't lose flow control.

In my honest opinion, there is never a need for goto.

If you are constructing arguments in order, you can destroy them in the reverse order at the exit and this lets you cleanly handle a failure in the middle of allocations:

    thing1 = allocate_thing1();
    if(!thing1) goto cleanup1;

    thing2 = allocate_thing2();
    if(!thing2) goto cleanup2;

    ...


    cleanup3:    deallocate_thing2(thing2);
    cleanup2:    deallocate_thing1(thing1);
    cleanup1:    return;

Because sometimes the tasks you need to perform cascade, and then you're repeating that cascade all over the place. As I pointed out upthread, check out the Linux kernel: http://lxr.free-electrons.com/source/kernel/fork.c?v=3.3#L42...

Notice the cascade after the 'out' label; each label after it is for a different level of cleanup needed, depending on how deep into the system call the function encountered the error. Also notice that this is basically the kind of code one would generate for exceptions.

In performance critical nested loops, goto is the only way to exit early. A typical example here is performing a matrix multiply. In cases like this, it is absolutely necessary, because C doesn't provide a more granular 'break'.

  • You could leave nested loops with a condition flag, which could produce something semantically equivalent to the goto. It seems like the logic here might be simple enough that the actual check could be eliminated in the generated code by a Sufficiently Smart Compiler (that could actually exist), if there was sufficient demand for it. I'm not sure it's actually more readable, though.

    • Yeah, of course I'm aware, it's just that there is a time/space trade-off, so I think folks who argue that goto should never be used or has no legitimate uses, are just taking too much of a hard-line.

      And I think it just highlights a lack of understanding about what might make goto "bad" in programming--IMHO it's "bad" when it makes control flow more complex, which undermines maintainability. Common "cleanup" idioms that only jump forward are not that bad, because they don't make control flow particularly more difficult to follow. (Whereas jumping backwards, especially across many state changes, can be very hard to follow.)

      1 reply →

    • I'd argue than a condition flag in this case would introduce code bloat (declare, initialize, check in the loop construct) and decrease readability compared to a goto Label.

      1 reply →