Error Checking In C
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 Stack Overflow the
Exception Handling In C
company Business Learn more about hiring developers or posting ads with us Stack Overflow Questions error checking c drive Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a community of 4.7 million c atoi error checking programmers, just like you, helping each other. Join them; it only takes a minute: Sign up Error handling in C code up vote 102 down vote favorite 59 What do you consider "best practice" when it
Type Checking In C
comes to error handling errors in a consistent way in a C library. There are two ways I've been thinking of: Always return error code. A typical function would look like this: MYAPI_ERROR getObjectSize(MYAPIHandle h, int* returnedSize); The always provide an error pointer approach: int getObjectSize(MYAPIHandle h, MYAPI_ERROR* returnedError); When using the first approach it's possible to write code like this where the error handling check is directly placed on the function call: int
Bound Checking In C
size; if(getObjectSize(h, &size) != MYAPI_SUCCESS) { // Error handling } Which looks better than the error handling code here. MYAPIError error; int size; size = getObjectSize(h, &error); if(error != MYAPI_SUCCESS) { // Error handling } However, I think using the return value for returning data makes the code more readable, It's obvious that something was written to the size variable in the second example. Do you have any ideas on why I should prefer any of those approaches or perhaps mix them or use something else? I'm not a fan of global error states since it tends to make multi threaded use of the library way more painful. EDIT: C++ specific ideas on this would also be interesting to hear about as long as they are not involving exceptions since it's not an option for me at the moment... c error-handling share|improve this question edited Nov 6 '13 at 19:09 ubershmekel 3,64013145 asked Dec 22 '08 at 10:46 Laserallan 6,71172956 add a comment| 17 Answers 17 active oldest votes up vote 50 down vote accepted I like the error as return-value way. If you're designing the api and you want to make use of your library as painless as possible think about these additions: store all possible error-states in one typedef'ed enum and use it in your li
known as exception handling). By convention, the programmer is expected to prevent errors from occurring in the first place, and test return values from functions. For objective c error handling example, -1 and NULL are used in several functions such as socket()
C Error Handling Goto
(Unix socket programming) or malloc() respectively to indicate problems that the programmer should be aware about. In a c error handling best practices worst case scenario where there is an unavoidable error and no way to recover from it, a C programmer usually tries to log the error and "gracefully" terminate the http://stackoverflow.com/questions/385975/error-handling-in-c-code program. There is an external variable called "errno", accessible by the programs after including
EOF that is defined for that purpose. But this return value tells you only that an error has occurred. http://www.gnu.org/s/libc/manual/html_node/Checking-for-Errors.html To find out what kind of error it was, you need to look at the error code stored in the variable errno. This variable is declared in the header https://news.ycombinator.com/item?id=3883310 file errno.h. Variable: volatile int errno The variable errno contains the system error number. You can change the value of errno. Since errno is declared volatile, it might be in c changed asynchronously by a signal handler; see Defining Handlers. However, a properly written signal handler saves and restores the value of errno, so you generally do not need to worry about this possibility except when writing signal handlers. The initial value of errno at program startup is zero. Many library functions are guaranteed to set it to checking in c certain nonzero values when they encounter certain kinds of errors. These error conditions are listed for each function. These functions do not change errno when they succeed; thus, the value of errno after a successful call is not necessarily zero, and you should not use errno to determine whether a call failed. The proper way to do that is documented for each function. If the call failed, you can examine errno. Many library functions can set errno to a nonzero value as a result of calling other library functions which might fail. You should assume that any library function might alter errno when the function returns an error. Portability Note: ISOC specifies errno as a “modifiable lvalue” rather than as a variable, permitting it to be implemented as a macro. For example, its expansion might involve a function call, like *__errno_location(). In fact, that is what it is on GNU/Linux and GNU/Hurd systems. The GNU C Library, on each system, does whatever is right for the particular system. There ar
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 the job done in the cleanest possible way, so you should use them for doing 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 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 1630 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 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 1630 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 1630 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 t