3 ms·
I hope I'm gonna stay Junior longer! I don't want to start using goto...
by Joky 10y ago
I hope I'm gonna stay Junior longer! I don't want to start using goto...
- koenigdavidmj 10y agoWithout goto, you get to maintain several copies of your cleanup code, all different: int insane() { FILE *a = open("a", "r"); if (!a) { return -1; } FILE *b = open("b", "r"); if (!b) { fclose(a); return -1; } FILE *c = open("c", "r"); if (!c) { fclose(a); fclose(b); return -1; } int rv = (do something with a, b, and c); fclose(a); fclose(b); fclose(c); return rv; } Now here's an example where you only need to maintain one copy of your cleanup code: int reasonable() { FILE *a = NULL; FILE *b = NULL; FILE *c = NULL; int rv = -1; a = open("a", "r"); if (!a) { goto out; } b = open("b", "r"); if (!b) { goto out; } c = open("c", "r"); if (!c) { goto out; } rv = (do something with a, b, and c); out: if (a) { fclose(a); } if (b) { fclose(b); } if (c) { fclose(c); } return rv; } Avoiding goto gets impossible the second you start doing socket twiddling, or message generation. Yes, languages with context managers (Python's with blocks), RAII (C++ or Rust), or defer (Go) make this easier, but some of us are stuck writing C sometimes.
- tzs 10y agoOf course in this case you can avoid both the repetition and the goto at the cost of more nesting: rv = -1; a = open(...); if (a) { b = open(...); if (b) { c = open(...); if (c) { rv = something(a,b,c); close(c); } close(b); } close(a); } return rv; I wonder if there is some sort of program organization analog of Heisenberg's uncertainty principle, where the product of some measure of repetition, some measure of non-structured jumping, and some measure of nesting must be greater than a certain value?