4 ms·
Goto for cleanup is not bad IMHO. I use it extensively... $ cd redis; grep goto *.c | wc -l 251 All the instances are like: goto cleanup; goto er
by antirez 13y ago
Goto for cleanup is not bad IMHO. I use it extensively...
$ cd redis; grep goto *.c | wc -l
251
All the instances are like:
goto cleanup;
goto error;
goto badfmt;
goto numargserr;
In this context is easy to read and makes the code structure better.
- coherentpony 13y agoI 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.
- dllthomas 13y agoIf 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;
- scott_s 13y agoBecause 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#L427 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.
- garenp 13y agoIn 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'.
- dllthomas 13y agoYou 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.
- garenp 13y agoYeah, 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.)
- dllthomas 13y ago"it's just that there is a time/space trade-off," I don't see a time-space tradeoff here. Compiled naively, I expect the version with flags to be slower and take more space. Compiled sufficiently smartly, I expect them to be equivalent. I expect real compilers to be close enough to the latter for most but not all purposes, but I think if the flag version was more readable and maintainable the place to focus (collectively, medium term) would be on making compilers smart enough. Obviously, in the short term on specific projects you do what you need to. "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." I agree, but that's because there are places where use of Go To makes things more readable and maintainable, not - primarily - because they are actually needed, per se, even with performance constraints (in the overwhelming majority of cases). '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.' I agree wholeheartedly.
- cmollis 13y agoagreed. Goto's are not bad at all, particularly when dealing with error scenarios. They avoid hack-y if-then error logic (sort of like try/catch/finally)
- dllthomas 13y agoGotos are bad when used for unconstrained flow control. Restricted use of gotos to implement exception handling is, as you say, not bad.
- agumonkey 13y agoalso suggested here http://c.learncodethehardway.org/book/ex20.html http://c.learncodethehardway.org/book/ex20.html