5 ms·
Gotos are trivial. They map directly to unconditional jumps at the assembly level. They're one of the best ways to implement exception handling in C (look at h
by AbacusAvenger 11y ago
Gotos are trivial. They map directly to unconditional jumps at the assembly level.
They're one of the best ways to implement exception handling in C (look at how the Linux kernel uses them).
It's also not unusual to have conditionals that don't nest. Of course, if you really want to avoid using a goto, you have the option of duplicating a lot of code in order to satisfy all the code paths, decreasing readability and making it harder to maintain. Or you can just use a goto and not worry about it.
I do understand why people want to avoid 'goto', but Dijkstra wasn't always right...
- deleted 11y ago[deleted]
- nitrogen 11y agoIf the compiler in question does tail call optimization (or even if not), maybe one could write a cleanup function that takes the place of the goto block, but this looks pretty ugly with all the parameters: int cleanup(void *ptr1, char *ptr2, struct foo *ptr3, int *ptr4, union xyz *ptr5, int ret) { free(ptr1); // etc. return ret; } // later... if(fail1) { return cleanup(a, b, c, d, e, -1); }
- hyc_symas 11y agoI was at JPL when we were developing these standards. C was still pretty new there, they used FORTRAN almost exclusively before that. In practice, this rule had little impact. The only time you could justify using a goto was for cleanup, and you could always end-run around the rule. ... blah blah ... if (error) goto fail; ... blah blah ... if (error) goto fail; ... blah blah ... fail: ... cleanup ... just gets turned into do { ... blah blah ... if (error) break; ... blah blah ... if (error) break; ... etc... } while (0); if (error) { ... cleanup ... }