Goto Error Handling
Contents |
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site About Us Learn more about arrow antipattern Stack Overflow the company Business Learn more about hiring developers or posting ads with goto cleanup c us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a c error handling best practices community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up Valid use of goto for error management in C? up vote 71 down vote favorite
C Goto
29 This question is actually a result of an interesting discussion at programming.reddit.com a while ago. It basically boils down to the following code: int foo(int bar) { int return_value = 0; if (!do_something( bar )) { goto error_1; } if (!init_stuff( bar )) { goto error_2; } if (!prepare_stuff( bar )) { goto error_3; } return_value = do_the_thing( bar ); error_3: cleanup_3(); error_2: cleanup_2(); error_1: cleanup_1(); return return_value; } misra c The usage of goto here appears to be the best way to go, resulting in the cleanest and most efficient code of all possibilities, or at least so it seems to me. Quoting Steve McConnell in Code Complete: The goto is useful in a routine that allocates resources, performs operations on those resources, and then deallocates the resources. With a goto, you can clean up in one section of the code. The goto reduces the likelihood of your forgetting to deallocate the resources in each place you detect an error. Another support for this approach comes from the Linux Device Drivers book, in this section. What do you think? Is this case a valid use for goto in C? Would you prefer other methods, which produce more convoluted and/or less efficient code, but avoid goto? c exception-handling error-handling goto share|improve this question edited Apr 21 at 9:28 Arnaud 1,35821237 asked Apr 25 '09 at 13:17 Eli Bendersky 121k49245328 stackoverflow.com/questions/3339946/… –karlphillip Nov 28 '11 at 20:53 @Eli: Why don't you remove the tags and place the function(cleanup_3();) in the parenthesis of if? –Fahad Uddin Dec 5 '11 at 13:47 @Akito: what do you mean? Could you post your suggestion as an answer with a compl
resources Windows Server 2012 resources Programs MSDN subscriptions Overview Benefits Administrators Students Microsoft Imagine Microsoft Student Partners ISV Startups TechRewards Events Community Magazine raii Forums Blogs Channel 9 Documentation APIs and reference Dev centers Retired content Samples We’re sorry. The content you requested has been removed. You’ll be auto redirected in 1 second. Visual Basic Language Reference Statements F-P Statements F-P Statements On Error Statement On Error Statement On Error Statement For Each...Next Statement For...Next Statement Function Statement http://stackoverflow.com/questions/788903/valid-use-of-goto-for-error-management-in-c Get Statement GoTo Statement If...Then...Else Statement Implements Statement Imports Statement (.NET Namespace and Type) Imports Statement (XML Namespace) Inherits Statement Interface Statement Mid Statement Module Statement Namespace Statement On Error Statement Operator Statement Option
single target inside a function) is just perfect for C error handling code. Don't be misguided by a silly principle of goto's being always bad. They get https://news.ycombinator.com/item?id=3883310 the job done in the cleanest possible way, so you should use them for doing https://silviocesare.wordpress.com/2007/10/24/a-good-use-of-goto-for-error-handling/ cleanups.The examples did not have any resources to clean up, and that is what makes error handling in C painful. In the absence of any cleanup routines, this will do: return ( do_something() == SUCCESS && do_something_else() == SUCCESS && do_final_thing() == SUCCESS) ? SUCCESS : FAILURE; Of course, once you add resources to clean up or error error handling codes that are meaningful (not just success/fail) error handling gets more painful.You should not try to perfect something as mundane as error handling. Just write the damn code and get over it. tspiteri 1636 days ago Why should the goto be to one single target? Multiple goto statements are good for multiple clean ups without adding indentation levels and without having artificially long logic ands. For example: int init_abc() { if (!init_a()) goto goto error handling err_a; if (!init_b()) goto err_b; if (!init_c()) goto err_c; return 1; err_c: cleanup_b(); err_b: cleanup_a(); err_a: return 0; } seems to be the cleanest way to do what it does in C. For what it's worth, it is the way a lot of error handling is done in the Linux kernel. exDM69 1636 days ago I guess it's fine to use multiple targets too. However, usually you can get away with one, because free(NULL) and similar cleanups tend to be no-ops. So you have something like: char *foo = 0, *bar = 0; if((foo = malloc(X)) == NULL || (bar = malloc(Y)) == NULL) goto cleanup; make_me_millions(foo, bar); cleanup: free(bar); free(foo); In this case, and many cases like it, there's no need to have two jump targets, because one is good enough. You'll have to declare the variables early on anyway to avoid warnings/errors from definitions that cross jump labels.So there's probably nothing wrong with multiple jump targets but that might not be needed with well-behaving cleanup functions. adestefan 1636 days ago because free(NULL) and similar cleanups tend to be no-ops. So you have something likeYou really need to check the specification on each function. free is defined that free(NULL) is no-op, but there are other things where that is not the case. Also, that cod
on October 24, 2007 | 1 Comment Not all use of goto is considered evil by C programmers. Used appropriately, it can make code easier to read, and increase code performance. It is often you have a series of mallocs.
static char *a, *b, *c, *d;
void do_initialization(void)
{
a=malloc(10);
b=malloc(10);
c=malloc(10);
d=malloc(10);
}
To be robus, each malloc should be checked for failure. The do_initialization should reflect either success or failure. The following code implements that, but introduces more bugs.
int do_initialization()
{
if ((a = malloc(10)) == NULL) return -1;
if ((b = malloc(10)) == NULL) return -1;
if ((c = malloc(10)) == NULL) return -1;
if ((d = malloc(10)) == NULL) return -1;
return 0;
}
Memory leaks have been introduced. Lets fix that.
int do_initializae()
{
if ((a = malloc(10)) == NULL) return -1;
if ((b = malloc(10)) == NULL) {
free(a);
return -1;
}
if ((c = malloc(10)) == NULL) {
free(b);
free(a);
return -1;
}
if ((d = malloc(10)) == NULL) {
free(c);
free(b);
free(a);
}
return 0;
}
That correctly implements do_initialization, but it appears somewhat redundant and can be hard to read in larger projects. A good use of goto can make the above code much better.
int do_initialization()
{
if ((a = malloc(10)) == NULL) return -1;
if ((b = malloc(10)) == NULL) goto err_a;
if ((c = malloc(10)) == NULL) goto err_b;
if ((d = malloc(10)) == NULL) goto err_c;
return 0;err_c: free(c);
err_b: free(b);
err_a: free(a);
return -1;
}The code demonstrated above is very often seen in production code. The opensource kernels and other large C projects, make extensive use of this type of construct.
Like this:Like Loading... Related This entry was posted in C Programming. Bookmark the permalink. ← Linux Kernel *fpos += count signed integer overflowbug Kernel Pointer Overflows in Read andWrites → One response to “A good use of goto for errorhandling” Dimitris Staikos | December 13, 2007 at 9:03 pm | Reply I use the following approach which I think is clearer, more easily extensible and maintainable because it only uses one label: p1=p2=…=pN=NULL; if (NULL == (p1=malloc(…))) goto cleanup; … if (NULL == (pN=malloc(…))) goto cleanup; return 0; cleanup:; if (NULL != p1) free(p1); … if (NULL != pN-1) free(pN-1); return