Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any good idioms for error handling in straight C programs?

Getting back in to some C work.

Many of my functions look like this:

int err = do_something(arg1, arg2, arg3, &result); 

With the intent the result gets populated by the function, and the return value is the status of the call.

The darkside is you get something naive like this:

int err = func1(...); if (!err) {     err = func2(...);     if (!err) {         err = func3(...);     } } return err; 

I could macro it I suppose:

#define ERR(x) if (!err) { err = (x) } int err = 0; ERR(func1(...)); ERR(func2(...)); ERR(func3(...)); return err; 

But that only works if I'm chaining function calls, vs doing other work.

Obviously Java, C#, C++ have exceptions that work very well for these kinds of things.

I'm just curious what other folks do and how other folks do error handling in their C programs nowadays.

like image 651
Will Hartung Avatar asked May 07 '10 16:05

Will Hartung


People also ask

How do you describe the proper error handling?

Error handling refers to the response and recovery procedures from error conditions present in a software application. In other words, it is the process comprised of anticipation, detection and resolution of application errors, programming errors or communication errors.

Does C support error handling?

C does not provide direct support for error handling (also 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.

What is error handling as used in programming?

Error handling refers to the routines in a program that respond to abnormal input or conditions. The quality of such routines is based on the clarity of the error messages and the options given to users for resolving the problem.


2 Answers

If you have resources that need to be released at the end, then sometimes the old trusty goto can be handy!

int major_func(size_t len) {     int err;     char *buf;      buf = malloc(len);      if (err = minor_func1(buf))         goto major_func_end;     if (err = minor_func2(buf))         goto major_func_end;     if (err = minor_func3(buf))         goto major_func_end;  major_func_end:     free(buf);     return err; } 
like image 106
Judge Maygarden Avatar answered Oct 04 '22 05:10

Judge Maygarden


Two typical patterns:

int major_func() {     int err = 0;      if (err = minor_func1()) return err;     if (err = minor_func2()) return err;     if (err = minor_func3()) return err;      return 0; }  int other_idea() {     int err = minor_func1();     if (!err)         err = minor_func2();     if (!err)         err = minor_func3();     return err;             }  void main_func() {     int err = major_func();     if (err)     {         show_err();         return;     }     happy_happy_joy_joy();      err = other_idea();     if (err)     {         show_err();         return;     }     happy_happy_joy_joy(); } 
like image 31
egrunin Avatar answered Oct 04 '22 06:10

egrunin