4 ms·
In C it's generally accepted that forward jumps using goto are okay because the version that avoids goto would be complicated and confusing. Often used for erro
by sjs 15y ago
In C it's generally accepted that forward jumps using goto are okay because the version that avoids goto would be complicated and confusing. Often used for error handling and memory management.
- sliverstorm 15y agoError handling because you want to make a beeline to the handler, and memory management because you need it to be quick and goto is cheap?
- sparky 15y agoIn both cases, to avoid duplicating code. If you malloc() something in your function and intend on free()ing it before returning, it's often considered best practices to write the return block (which includes the free()s) once, and use "goto returnblocklabel" if you need to return early. So rather than this: void test() { int *x = malloc(1000); int *y = malloc(1000); for(int i = 0; i < 999; i++) { if(badThing) { free(x); free(y); return; } doStuff() if(otherBadThing) { free(x); free(y); return; } } free(x); free(y); return; } You'd have: void test() { int *x = malloc(1000); int *y = malloc(1000); for(int i = 0; i < 999; i++) { if(badThing) goto ret; doStuff() if(otherBadThing) goto ret; } ret: free(x); free(y); return; }
- Jach 15y agoI realize your example is contrived, but a simple 'break' statement (which in essence is a goto...) would work just as well. :) I somewhat vaguely recall a situation in my C class that I wanted to use goto to avoid duplicate code but the professor had previously threatened huge negative points if his scripts detected one. (That whole semester was just as much about conforming your code to his narrow specifics because "that's what happens in the real world." as learning C.)
- Peaker 15y agoCan you explain what you mean by use of gotos for memory management?
- sjs 15y agoHere's an example: void do_stuff(char *name) { char *my_name = strdup(name); if (condition_signalling_no_work()) goto done; if (do_something_with(my_name)) goto done; ... done: free(my_name); return; } If it helps think of it as a finally block. The function does some things and no matter what it has to run that block at the end.
- Peaker 15y agoAh, so for resource cleanup in general, not memory management in particular.