C 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 exceptions c Learn more about Stack Overflow the company Business Learn more about hiring developers
C Error Handling Best Practices
or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack
C Sharp Error Handling
Overflow Community Stack Overflow is a 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 Error Handling Errno
C? up vote 71 down vote favorite 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 handling c programming ); error_3: cleanup_3(); error_2: cleanup_2(); error_1: cleanup_1(); return return_value; } 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,33821236 asked Apr 25 '09 at 13:17 Eli Bendersky 121k49243327 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
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 Stack Overflow the company c exit Business Learn more about hiring developers or posting ads with us Programmers Questions Tags Users objective c error handling Badges Unanswered Ask Question _ Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about c error handling goto software development. Join them; it only takes a minute: Sign up Here's how it works: Anybody can ask a question Anybody can answer The best answers are voted up and rise to the top Is this a http://stackoverflow.com/questions/788903/valid-use-of-goto-for-error-management-in-c decent use-case for goto in C? up vote 38 down vote favorite 9 I really hesitate to ask this, because I don't want to "solicit debate, arguments, polling, or extended discussion" but I'm new to C and want to gain more insight into common patterns used in the language. I recently heard some distaste for the goto command, but I've also recently found a decent use-case for it. Code like this: error = http://programmers.stackexchange.com/questions/154974/is-this-a-decent-use-case-for-goto-in-c function_that_could_fail_1(); if (!error) { error = function_that_could_fail_2(); if (!error) { error = function_that_could_fail_3(); ...to the n-th tab level! } else { // deal with error, clean up, and return error code } } else { // deal with error, clean up, and return error code } If the clean-up part is all very similar, could be written a little prettier (my opinion?) like this: error = function_that_could_fail_1(); if(error) { goto cleanup; } error = function_that_could_fail_2(); if(error) { goto cleanup; } error = function_that_could_fail_3(); if(error) { goto cleanup; } ... cleanup: // deal with error if it exists, clean up // return error code Is this a common or acceptable use-case of goto in C? Is there a different/better way to do this? c design-patterns goto share|improve this question edited Jun 30 '12 at 13:21 Bill the Lizard 7,48683386 asked Jun 30 '12 at 1:49 Robz 9213910 2 See also this question (and my answer). –Keith Thompson Jun 30 '12 at 3:32 1 That's probably the one excuse for goto, of course if you really object you can use c++ and exceptions - but that's just goto with a sugar coating –Martin Beckett Jun 30 '12 at 3:37 1 @DeadMG You'd still end up with lots of nesting. –Izkata Jun 30 '12 at 3:40 4 @Dea
program comes out of an error condition gracefully. On encountering an error a program must rollback and free-up various resources allocated during the course of execution. Ideally, the program should get back to a state where it http://blog.staila.com/?p=114 was consistent before the error happened. Why error handling is important? Absence of error http://blog.regehr.org/archives/894 handling or a buggy error handling can lead a program or the system as whole to an inconsistent state. Often many fatal programming bugs such as memory leaks, dead locks, data race conditions etc. are the results of an improper error handling. Especially in a programming environment where resources are scarce and margin of error is thin adapting to a good error handling error handling technique becomes even more important. Common error handling techniques There are mainly two techniques used by professional C programmers to handle errors. The first one is where a program on encountering an error un-dos the changes and returns from the same code location. As a sample following is a C function that inserts some string in a linked list node if the string is already not present. It returns pointer to head of the c error handling linked list in case of success or NULL otherwise. Notice the error handling technique used in the program. struct lnode { char *str; struct lnode *next; }; struct lnode *insert(char *data, int len, struct lnode *list) { struct lnode *p, *q; p = (struct lnode *)malloc(sizeof(struct lnode)); if ( NULL == p ) { return NULL; } p->str = (char *)malloc(sizeof(char)*len); if ( NULL == p->str ) { // free node before returning. free ( p ); return NULL; } memcpy ( p->str, data, len ); if(NULL == list) { p->next = NULL; list = p; } else { q = list; while(q->next != NULL) { // check for duplicates if (0 == strcmp(q->str,p->str)) { // free string and node free(p->str); free(p); return NULL; } q = q->next; } p->next = q->next; q->next = p; } return list; } In this case error is handled by freeing up memory allocated so far and returning from the same place. It is a very simple way of handling error gracefully but it has several demerits. It makes the function look complicated as it has multiple exit points (return statements). In this approach if the error handling part of the code grows large then the code can become really unmanageable. Thus such a technique of error handling can be used, at the most, only in functions which are quite s
number of legitimate uses in well-structured code including an idiom seen in systems code where a failure partway through a sequence of stateful operations necessitates unwinding the operations that have already completed. For example: int init_device (void) { if (allocate_memory() != SUCCESS) goto out1; if (setup_interrupts() != SUCCESS) goto out2; if (setup_registers() != SUCCESS) goto out3; .. more logic ... return SUCCESS; out3: teardown_interrupts(); out2: free_memory(); out1: return ERROR; } Is goto necessary to make this code work? Certainly not. We can write this instead: int init_device (void) { if (allocate_memory() == SUCCESS) { if (setup_interrupts() == SUCCESS) { if (setup_registers() == SUCCESS) { ... more logic ... return SUCCESS; } teardown_interrupts(); } free_memory(); } return ERROR; } And in fact a decent compiler will turn both of these into the same object code, or close enough. Even so, many people, including me, prefer the goto version, perhaps because it doesn't result in as much unsightly indentation of the central part of the function. Tonight's mainline Linux kernel contains about 100,000 instances of the keyword "goto". Here's a nice clean goto chain of depth 10. Here are the goto targets that appear more than 200 times: out (23228 times) error (4240 times) err (4184 times) fail (3250 times) done (3179 times) exit (1825 times) bail (1539 times) out_unlock (1219 times) err_out (1165 times) out_free (1053 times) nla_put_failure (929 times) failed (849 times) out_err (841 times) unlock (831 times) cleanup (713 times) drop (535 times) retry (533 times) again (486 times) end (469 times) bad (454 times) errout (376 times) err1 (362 times) found (362 times) error_ret (331 times) error_out (276 times) err2 (271 times) fail1 (264 times) err_free (262 times) next (260 times) out1 (242 times) leave (240 times) abort (228 times) restart (224 times) badframe (221 times) out2 (218 times) error0 (208 times) fail2 (208 times) "goto out;" is indeed a classic. This kind of code has been on my mind lately since I'm trying to teach my operating systems class about how in kernel code, you can't just bail out and expect someone else to clean up the mess. Author regehrPosted on February 4, 2013May 9, 2016Categories Computer Science 29 thoughts on “Use of Goto in Systems Code” Phil Miller says: February 4, 2013 at 10:06 pm I wonder how much of this code could be replaced by simple C++-style RAII, where the entity-appropriate cleanup code runs upon it going out of scope. Even further, though, how many bugs would be obviated, avoided, or fixed by making that change? That question might be answerable by fairly sha