C error-handling exception like - c

I would like to do some error handling in C. I like C# exceptions so decided to do something like that. The goals are:
One line error handling in caller functions like throw exception in C#
Breaks the code sequence in caller function where the error happened
To know the file/line where the error happened
Verbal description about the error
What do you think is there any problem with this approach?
The caller function:
EError activate_add(uint32_t key)
{
if (activate_bufferSize+1>=activate_bufferMax) THROW_ERROR("activate list full");
activate_buffer[activate_bufferSize].Id = activate_bufferSize+1;
activate_buffer[activate_bufferSize].StoredKey = key;
activate_bufferSize++;
TRY(activate_saveToEEProm());
NO_ERROR();
}
My solution is the following:
#ifndef ERROR_H_
#define ERROR_H_
typedef enum
{
Message_None,
Message_Error,
Message_Warning,
Message_Info
}EMessage_type;
typedef struct
{
EMessage_type message_type;
char* message;
const char* file;
uint32_t line;
}EErrorStruct,*EError;
#define THROW_ERROR(message, ...) { EError __err=GET_MESSAGE(Message_Error,(char*)__FILE__,__LINE__,message,##__VA_ARGS__); SEND_MESSAGE(__err); return __err;}
#define TRY(__x) { EError __err = __x; if (__err->message_type==Message_Error) { return __err;}}
#define TRYHAL(__x) { HAL_StatusTypeDef __res = __x; if (__res != HAL_OK) { THROW_ERROR("HAL problem: %u",__res);}}
#define TRYFAT(__x) { FRESULT __res = __x; if (__res != FR_OK) { THROW_ERROR("FAT problem: %u",__res);}}
#define NO_ERROR() { return GET_MESSAGE(Message_None,NULL,0,NULL,0);}
#define SEND_ERROR(message , ...) { SEND_MESSAGE(GET_MESSAGE(Message_Error,(char*)__FILE__,__LINE__,message,##__VA_ARGS__)); }
#define SEND_WARN(message , ...) { SEND_MESSAGE(GET_MESSAGE(Message_Warning,(char*)__FILE__,__LINE__,message,##__VA_ARGS__)); }
#define SEND_INFO(message , ...) { SEND_MESSAGE(GET_MESSAGE(Message_Info,(char*)__FILE__,__LINE__,message,##__VA_ARGS__)); }
EError GET_MESSAGE(EMessage_type messagetype,const char* file, uint32_t line,const char *format, ... );
void SEND_MESSAGE(EError err);
uint8_t ISFAILED(EError err);
#endif /* ERROR_H_ */
The source file
#include <error.h>
#include "stdio.h"
#include "stdarg.h"
static EErrorStruct error;
static const EError m = &error;
static char buffer[300];
EError GET_MESSAGE(EMessage_type messagetype,const char* file, uint32_t line,const char *format, ... )
{
va_list args;
va_start(args,format);
vsprintf(buffer, format, args);
va_end(args);
m->message = buffer;
m->message_type = messagetype;
m->file = file;
m->line = line;
return m;
}
void SEND_MESSAGE(EError err)
{
switch (err->message_type) {
case Message_Error:
printf("ERRO: %s \r\n\t\t\t\t\t\t\t\t\t\t at %s line: %u\r\n",err->message,err->file,(unsigned int)err->line);
break;
case Message_Warning:
printf("WARN: %s \r\n\t\t\t\t\t\t\t\t\t\t at %s line: %u\r\n",err->message,err->file,(unsigned int)err->line);
break;
case Message_Info:
printf("INFO: %s \r\n\t\t\t\t\t\t\t\t\t\t at %s line: %u\r\n",err->message,err->file,(unsigned int)err->line);
break;
default:
break;
}
}
uint8_t ISFAILED(EError err)
{
if (err->message_type == Message_Error) return 1;
return 0;
}

The following are all widely considered as bad practice:
Function-like macros.
Variadic macros.
Variadic functions.
Inventing your own language features through macros.
Using non-standard language features such as ##__VA_ARGS__.
There are many reasons why these are bad practice: non-existent type safety, very hard to read, hard to debug/maintain, portability and so on.
Thus combining all of the above into a single program is a very bad idea.
Error handing in C is handled through a de facto industry standard, which basically goes like this:
Error codes are defined through enums.
The return value of any API function is reserved for the error code.
Upon error the function returns an error code.
Compilers are set to a warning level where you get a warning if you ignore the result of a function.
Source code documentation states what will/will not happen with other parameters upon success and error.
This is what other C programmers expect and immediately understand. They do not understand or expect some home-brewed exception handling system.
In addition, there is a lot of criticism against exception handling in languages that do support it. See Why is exception handling bad?

Related

How to pass a string as a macro?

There are many functions in the C libraries that require users to input with macros.
I wonder, if I have an array of strings, with contents of macros, like so:
char s[][3] = {"SIGINT", "SIGKILL", "SIGSTOP"};
How can I pass these strings as macros? (Like so:)
signal(s[0], do_something);
with do_something is a function pointer.
(and yes, technically I can pass ints in this case, but... hypothetically, ya know?)
EDIT:
As #RemyLebeau and SGeorgiades point out, the "SIGINT",... are aliases for integer consts, and therefore can be stored in an int array, like so:
int s[3] = {SIGINT, SIGKILL, SIGSTOP};
Although SGeorgiades and Remy Lebeau already gave you the answer, here is something that I've used in the past to allow conversion and pretty printing of signal numbers and names:
#include <stdio.h>
#include <signal.h>
#include <string.h>
struct sigfun {
int signo;
const char *signame;
};
#define SIGFUN(_sig) \
{ \
.signo = _sig, \
.signame = #_sig \
}
struct sigfun siglist[] = {
SIGFUN(SIGINT),
SIGFUN(SIGKILL),
SIGFUN(SIGSTOP),
// ...
{ .signo = 0, .signame = NULL }
};
#define SIGFORALL(_sig) \
_sig = siglist; _sig->signame != NULL; ++_sig
int
signame_to_signo(const char *signame)
{
struct sigfun *sig;
for (SIGFORALL(sig)) {
if (strcmp(sig->signame,signame) == 0)
break;
}
return sig->signo;
}
const char *
signo_to_signame(int signo)
{
struct sigfun *sig;
for (SIGFORALL(sig)) {
if (signo == sig->signo)
break;
}
return sig->signame;
}
UPDATE:
why not put for into SIGFORALL? –
tstanisl
For a few reasons ...
I've done that before (e.g.):
#define SIGFORALL(_sig) \
for (_sig = siglist; _sig->signame != 0; ++_sig)
SIGFORALL(sig) {
// do stuff
}
This tends to confuse certain IDEs and/or tools that parse the code without running it through the preprocessor.
It's also more difficult for programmers to quickly (without digesting the macro) skip over it.
They don't see a for and have trouble figuring out what SIGFORALL(sig) { does.
Is the macro a wrapper for if, for, or while?
With:
#define SIGFORALL(_sig) \
_sig = siglist; _sig->signame != 0; ++_sig
for (SIGFORALL(sig)) {
// do stuff
}
there is a better chance they can continue around the construct because they can understand (i.e. skip over) the for (...) [syntactically] without having to know what the macro is doing. That is, nobody has to "drill down" into the macro unless they wish to.
Another reason is that without the for in the macro, we can add extra code to the for loop's initialization and iteration expressions. It's more flexible.
For example, I've used a similar macro for linked list traversal and wanted to know the index/count of an element:
#define LLFORALL(_node) \
_node = nodelist; _node != NULL; _node = _node->next
int idx;
for (idx = 0, LLFORALL(node), ++idx) {
if (node->value == 5)
printf("found value at index %d\n",idx);
}
There's no absolute rule about this. Ultimately, it's a [personal] style preference.
Perhaps what you want instead is:
int s[3] = { SIGINT, SIGKILL, SIGSTOP };
signal(s[0], do_something);

Let a macro count its invocations

I've a huge C project with a module reading and managing configuration data. If I have to add a new configuration parameter, I'll have to edit several functions, e.g. as pseudo-code:
void read_configuration(config *c) {
read_param("p1", c->p1);
read_param("p2", c->p2);
read_param("p3", c->p3);
/* ... */
}
void dump_configuration(config *c) {
dump_param("p1", c->p1);
dump_param("p2", c->p2);
dump_param("p3", c->p3);
/* ... */
}
Is there a way to ensure by macro at compile time, that each location has at least the same count of parameters? I thought of making dump_param some kind of macro counting the invocations and then add something like
#if nr_read != nr_dump
#error "You forgot something, idiot!"
#endif
at the end of the module. I can't find a method to make the macro count its invocations, though...
Since the list of parameters is the same in both functions, how about factoring that out and avoid any possible mismatch ?
Using X-macros
#define X_CONFIG_PARAMS(config) \
X("p1", (config).p1) \
X("p2", (config).p2) \
X("p3", (config).p3)
void read_configuration(config *c) {
#define X(name, param) read_param(name, &param);
X_CONFIG_PARAMS(*c)
#undef X
}
void dump_configuration(config *c) {
#define X(name, param) dump_param(name, &param);
X_CONFIG_PARAMS(*c)
#undef X
}
Using function pointers
void alter_config(config *c, void(*func)(char const *name, Param *param)) {
func("p1", &c->p1);
func("p2", &c->p2);
func("p3", &c->p3);
}
void read_configuration(config *c) {
alter_config(c, read_param);
}
void dump_configuration(config *c) {
alter_config(c, dump_param);
}
Using an array and offsetof
struct param_info {
char const *name;
size_t config_offs;
};
param_info allParams[] = {
{"p1", offsetof(config, p1)},
{"p2", offsetof(config, p2)},
{"p3", offsetof(config, p3)}
};
void read_configuration(config *c) {
size_t paramCount = sizeof allParams / sizeof *allParams;
for(size_t i = 0; i < paramCount; ++i) {
Param *p = (Param*)((char*)config + allParams[i].config_offs);
read_param(allParams[i].name, p);
}
}
void dump_configuration(config *c) {
size_t paramCount = sizeof allParams / sizeof *allParams;
for(size_t i = 0; i < paramCount; ++i) {
Param *p = (Param*)((char*)config + allParams[i].config_offs);
dump_param(allParams[i].name, p);
}
}
I would rather let the preprocessor write the code in the first place.
It could look something like this:
Define the list of parameters in a separate file, say parameters.inc:
PARAM (p1)
PARAM (p2)
...
Then in the source code locally define the macro PARAM as required and let the preprocessor include and expand the contents of parameters.inc:
void read_configuration(config *c) {
#define PARAM(NAME) read_param(#NAME, c->NAME);
#include "parameters.inc"
#undef PARAM
}
void dump_configuration(config *c) {
#define PARAM(NAME) dump_param(#NAME, c->NAME);
#include "parameters.inc"
#undef PARAM
}
I don't think you can do this at compile time without ugly hacks.
What you could do: add a test to your test suite which replaces the header that contains the read_param() and dump_param() macros so they generate code which only updates a counter. Then, in the main() function of that test, place an assertion that compares both counters and fails if they're not equal.
You do have a test suite and run it at compile time, right? ;-)
However, I do agree with the comment that it's probably better to do this differently. In an approach called "table-driven programming", you turn the macro definition and data definition on their head (that is, you have the #define in your .c file and the use of the macro in the header rather than the other way around), you don't have this problem. Poul-Henning Kamp, of FreeBSD fame, explains very well how to that here.

Try catch statements in C

I was thinking today about the try/catch blocks existent in another languages. Googled for a while this but with no result. From what I know, there is not such a thing as try/catch in C. However, is there a way to "simulate" them?
Sure, there is assert and other tricks but nothing like try/catch, that also catch the raised exception. Thank you
C itself doesn't support exceptions but you can simulate them to a degree with setjmp and longjmp calls.
static jmp_buf s_jumpBuffer;
void Example() {
if (setjmp(s_jumpBuffer)) {
// The longjmp was executed and returned control here
printf("Exception happened here\n");
} else {
// Normal code execution starts here
Test();
}
}
void Test() {
// Rough equivalent of `throw`
longjmp(s_jumpBuffer, 42);
}
This website has a nice tutorial on how to simulate exceptions with setjmp and longjmp
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
You use goto in C for similar error handling situations.
That is the closest equivalent of exceptions you can get in C.
Ok, I couldn't resist replying to this. Let me first say I don't think it's a good idea to simulate this in C as it really is a foreign concept to C.
We can use abuse the preprocessor and local stack variables to give use a limited version of C++ try/throw/catch.
Version 1 (local scope throws)
#include <stdbool.h>
#define try bool __HadError=false;
#define catch(x) ExitJmp:if(__HadError)
#define throw(x) {__HadError=true;goto ExitJmp;}
Version 1 is a local throw only (can't leave the function's scope). It does rely on C99's ability to declare variables in code (it should work in C89 if the try is first thing in the function).
This function just makes a local var so it knows if there was an error and uses a goto to jump to the catch block.
For example:
#include <stdio.h>
#include <stdbool.h>
#define try bool __HadError=false;
#define catch(x) ExitJmp:if(__HadError)
#define throw(x) {__HadError=true;goto ExitJmp;}
int main(void)
{
try
{
printf("One\n");
throw();
printf("Two\n");
}
catch(...)
{
printf("Error\n");
}
return 0;
}
This works out to something like:
int main(void)
{
bool HadError=false;
{
printf("One\n");
{
HadError=true;
goto ExitJmp;
}
printf("Two\n");
}
ExitJmp:
if(HadError)
{
printf("Error\n");
}
return 0;
}
Version 2 (scope jumping)
#include <stdbool.h>
#include <setjmp.h>
jmp_buf *g__ActiveBuf;
#define try jmp_buf __LocalJmpBuff;jmp_buf *__OldActiveBuf=g__ActiveBuf;bool __WasThrown=false;g__ActiveBuf=&__LocalJmpBuff;if(setjmp(__LocalJmpBuff)){__WasThrown=true;}else
#define catch(x) g__ActiveBuf=__OldActiveBuf;if(__WasThrown)
#define throw(x) longjmp(*g__ActiveBuf,1);
Version 2 is a lot more complex but basically works the same way. It uses a
long jump out of the current function to the try block. The try block then
uses an if/else to skip the code block to the catch block which check the local
variable to see if it should catch.
The example expanded again:
jmp_buf *g_ActiveBuf;
int main(void)
{
jmp_buf LocalJmpBuff;
jmp_buf *OldActiveBuf=g_ActiveBuf;
bool WasThrown=false;
g_ActiveBuf=&LocalJmpBuff;
if(setjmp(LocalJmpBuff))
{
WasThrown=true;
}
else
{
printf("One\n");
longjmp(*g_ActiveBuf,1);
printf("Two\n");
}
g_ActiveBuf=OldActiveBuf;
if(WasThrown)
{
printf("Error\n");
}
return 0;
}
This uses a global pointer so the longjmp() knows what try was last run.
We are using abusing the stack so child functions can also have a try/catch block.
Using this code has a number of down sides (but is a fun mental exercise):
It will not free allocated memory as there are no deconstructors being called.
You can't have more than 1 try/catch in a scope (no nesting)
You can't actually throw exceptions or other data like in C++
Not thread safe at all
You are setting up other programmers for failure because they will likely not notice the hack and try using them like C++ try/catch blocks.
In C99, you can use setjmp/longjmp for non-local control flow.
Within a single scope, the generic, structured coding pattern for C in the presence of multiple resource allocations and multiple exits uses goto, like in this example. This is similar to how C++ implements destructor calls of automatic objects under the hood, and if you stick to this diligently, it should allow you for a certain degree of cleanness even in complex functions.
While some of the other answers have covered the simple cases using setjmp and longjmp, in a real application there's two concerns that really matter.
Nesting of try/catch blocks. Using a single global variable for your jmp_buf will make these not work.
Threading. A single global variable for you jmp_buf will cause all kinds of pain in this situation.
The solution to these is to maintain a thread-local stack of jmp_buf that get updated as you go. (I think this is what lua uses internally).
So instead of this (from JaredPar's awesome answer)
static jmp_buf s_jumpBuffer;
void Example() {
if (setjmp(s_jumpBuffer)) {
// The longjmp was executed and returned control here
printf("Exception happened\n");
} else {
// Normal code execution starts here
Test();
}
}
void Test() {
// Rough equivalent of `throw`
longjump(s_jumpBuffer, 42);
}
You'd use something like:
#define MAX_EXCEPTION_DEPTH 10;
struct exception_state {
jmp_buf s_jumpBuffer[MAX_EXCEPTION_DEPTH];
int current_depth;
};
int try_point(struct exception_state * state) {
if(current_depth==MAX_EXCEPTION_DEPTH) {
abort();
}
int ok = setjmp(state->jumpBuffer[state->current_depth]);
if(ok) {
state->current_depth++;
} else {
//We've had an exception update the stack.
state->current_depth--;
}
return ok;
}
void throw_exception(struct exception_state * state) {
longjump(state->current_depth-1,1);
}
void catch_point(struct exception_state * state) {
state->current_depth--;
}
void end_try_point(struct exception_state * state) {
state->current_depth--;
}
__thread struct exception_state g_exception_state;
void Example() {
if (try_point(&g_exception_state)) {
catch_point(&g_exception_state);
printf("Exception happened\n");
} else {
// Normal code execution starts here
Test();
end_try_point(&g_exception_state);
}
}
void Test() {
// Rough equivalent of `throw`
throw_exception(g_exception_state);
}
Again a more realistic version of this would include some way to store error information into the exception_state, better handling of MAX_EXCEPTION_DEPTH (maybe using realloc to grow the buffer, or something like that).
DISCLAIMER: The above code was written without any testing whatsoever. It is purely so you get an idea of how to structure things. Different systems and different compilers will need to implement the thread local storage differently. The code probably contains both compile errors and logic errors - so while you're free to use it as you choose, TEST it before using it ;)
This is another way to do error handling in C which is more performant than using setjmp/longjmp. Unfortunately, it will not work with MSVC but if using only GCC/Clang is an option, then you might consider it. Specifically, it uses the "label as value" extension, which allows you to take the address of a label, store it in a value and and jump to it unconditionally. I'll present it using an example:
GameEngine *CreateGameEngine(GameEngineParams const *params)
{
/* Declare an error handler variable. This will hold the address
to jump to if an error occurs to cleanup pending resources.
Initialize it to the err label which simply returns an
error value (NULL in this example). The && operator resolves to
the address of the label err */
void *eh = &&err;
/* Try the allocation */
GameEngine *engine = malloc(sizeof *engine);
if (!engine)
goto *eh; /* this is essentially your "throw" */
/* Now make sure that if we throw from this point on, the memory
gets deallocated. As a convention you could name the label "undo_"
followed by the operation to rollback. */
eh = &&undo_malloc;
/* Now carry on with the initialization. */
engine->window = OpenWindow(...);
if (!engine->window)
goto *eh; /* The neat trick about using approach is that you don't
need to remember what "undo" label to go to in code.
Simply go to *eh. */
eh = &&undo_window_open;
/* etc */
/* Everything went well, just return the device. */
return device;
/* After the return, insert your cleanup code in reverse order. */
undo_window_open: CloseWindow(engine->window);
undo_malloc: free(engine);
err: return NULL;
}
If you so wish, you could refactor common code in defines, effectively implementing your own error-handling system.
/* Put at the beginning of a function that may fail. */
#define declthrows void *_eh = &&err
/* Cleans up resources and returns error result. */
#define throw goto *_eh
/* Sets a new undo checkpoint. */
#define undo(label) _eh = &&undo_##label
/* Throws if [condition] evaluates to false. */
#define check(condition) if (!(condition)) throw
/* Throws if [condition] evaluates to false. Then sets a new undo checkpoint. */
#define checkpoint(label, condition) { check(condition); undo(label); }
Then the example becomes
GameEngine *CreateGameEngine(GameEngineParams const *params)
{
declthrows;
/* Try the allocation */
GameEngine *engine = malloc(sizeof *engine);
checkpoint(malloc, engine);
/* Now carry on with the initialization. */
engine->window = OpenWindow(...);
checkpoint(window_open, engine->window);
/* etc */
/* Everything went well, just return the device. */
return device;
/* After the return, insert your cleanup code in reverse order. */
undo_window_open: CloseWindow(engine->window);
undo_malloc: free(engine);
err: return NULL;
}
A quick google search yields kludgey solutions such as this that use setjmp/longjmp as others have mentioned. Nothing as straightforward and elegant as C++/Java's try/catch. I'm rather partial to Ada's exception handling myself.
Check everything with if statements :)
This can be done with setjmp/longjmp in C. P99 has a quite comfortable toolset for this that also is consistent with the new thread model of C11.
In C, you can "emulate" exceptions along with automatic "object reclamation" through manual use of if + goto for explicit error handling.
I often write C code like the following (boiled down to highlight error handling):
#include <assert.h>
typedef int errcode;
errcode init_or_fail( foo *f, goo *g, poo *p, loo *l )
{
errcode ret = 0;
if ( ( ret = foo_init( f ) ) )
goto FAIL;
if ( ( ret = goo_init( g ) ) )
goto FAIL_F;
if ( ( ret = poo_init( p ) ) )
goto FAIL_G;
if ( ( ret = loo_init( l ) ) )
goto FAIL_P;
assert( 0 == ret );
goto END;
/* error handling and return */
/* Note that we finalize in opposite order of initialization because we are unwinding a *STACK* of initialized objects */
FAIL_P:
poo_fini( p );
FAIL_G:
goo_fini( g );
FAIL_F:
foo_fini( f );
FAIL:
assert( 0 != ret );
END:
return ret;
}
This is completely standard ANSI C, separates the error handling away from your mainline code, allows for (manual) stack unwinding of initialized objects much like C++ does, and it is completely obvious what is happening here. Because you are explicitly testing for failure at each point it does make it easier to insert specific logging or error handling at each place an error can occur.
If you don't mind a little macro magic, then you can make this more concise while doing other things like logging errors with stack traces. For example:
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define TRY( X, LABEL ) do { if ( ( X ) ) { fprintf( stderr, "%s:%d: Statement '%s' failed! %d, %s\n", __FILE__, __LINE__, #X, ret, strerror( ret ) ); goto LABEL; } while ( 0 )
typedef int errcode;
errcode init_or_fail( foo *f, goo *g, poo *p, loo *l )
{
errcode ret = 0;
TRY( ret = foo_init( f ), FAIL );
TRY( ret = goo_init( g ), FAIL_F );
TRY( ret = poo_init( p ), FAIL_G );
TRY( ret = loo_init( l ), FAIL_P );
assert( 0 == ret );
goto END;
/* error handling and return */
FAIL_P:
poo_fini( p );
FAIL_G:
goo_fini( g );
FAIL_F:
foo_fini( f );
FAIL:
assert( 0 != ret );
END:
return ret;
}
Of course, this isn't as elegant as C++ exceptions + destructors. For example, nesting multiple error handling stacks within one function this way isn't very clean. Instead, you'd probably want to break those out into self contained sub functions that similarly handle errors, initialize + finalize explicitly like this.
This also only works within a single function and won't keep jumping up the stack unless higher level callers implement similar explicit error handling logic, whereas a C++ exception will just keep jumping up the stack until it finds an appropriate handler. Nor does it allow you to throw an arbitrary type, but instead only an error code.
Systematically coding this way (i.e. - with a single entry and single exit point) also makes it very easy to insert pre and post ("finally") logic that will execute no matter what. You just put your "finally" logic after the END label.
Warning: the following is not very nice but it does the job.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned int id;
char *name;
char *msg;
} error;
#define _printerr(e, s, ...) fprintf(stderr, "\033[1m\033[37m" "%s:%d: " "\033[1m\033[31m" e ":" "\033[1m\033[37m" " ‘%s_error’ " "\033[0m" s "\n", __FILE__, __LINE__, (*__err)->name, ##__VA_ARGS__)
#define printerr(s, ...) _printerr("error", s, ##__VA_ARGS__)
#define printuncaughterr() _printerr("uncaught error", "%s", (*__err)->msg)
#define _errordef(n, _id) \
error* new_##n##_error_msg(char* msg) { \
error* self = malloc(sizeof(error)); \
self->id = _id; \
self->name = #n; \
self->msg = msg; \
return self; \
} \
error* new_##n##_error() { return new_##n##_error_msg(""); }
#define errordef(n) _errordef(n, __COUNTER__ +1)
#define try(try_block, err, err_name, catch_block) { \
error * err_name = NULL; \
error ** __err = & err_name; \
void __try_fn() try_block \
__try_fn(); \
void __catch_fn() { \
if (err_name == NULL) return; \
unsigned int __##err_name##_id = new_##err##_error()->id; \
if (__##err_name##_id != 0 && __##err_name##_id != err_name->id) \
printuncaughterr(); \
else if (__##err_name##_id != 0 || __##err_name##_id != err_name->id) \
catch_block \
} \
__catch_fn(); \
}
#define throw(e) { *__err = e; return; }
_errordef(any, 0)
Usage:
errordef(my_err1)
errordef(my_err2)
try ({
printf("Helloo\n");
throw(new_my_err1_error_msg("hiiiii!"));
printf("This will not be printed!\n");
}, /*catch*/ any, e, {
printf("My lovely error: %s %s\n", e->name, e->msg);
})
printf("\n");
try ({
printf("Helloo\n");
throw(new_my_err2_error_msg("my msg!"));
printf("This will not be printed!\n");
}, /*catch*/ my_err2, e, {
printerr("%s", e->msg);
})
printf("\n");
try ({
printf("Helloo\n");
throw(new_my_err1_error());
printf("This will not be printed!\n");
}, /*catch*/ my_err2, e, {
printf("Catch %s if you can!\n", e->name);
})
Output:
Helloo
My lovely error: my_err1 hiiiii!
Helloo
/home/naheel/Desktop/aa.c:28: error: ‘my_err2_error’ my msg!
Helloo
/home/naheel/Desktop/aa.c:38: uncaught error: ‘my_err1_error’
Keep on mind that this is using nested functions and __COUNTER__. You'll be on the safe side if you're using gcc.
Redis use goto to simulate try/catch, IMHO it is very clean and elegant:
/* Save the DB on disk. Return REDIS_ERR on error, REDIS_OK on success. */
int rdbSave(char *filename) {
char tmpfile[256];
FILE *fp;
rio rdb;
int error = 0;
snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid());
fp = fopen(tmpfile,"w");
if (!fp) {
redisLog(REDIS_WARNING, "Failed opening .rdb for saving: %s",
strerror(errno));
return REDIS_ERR;
}
rioInitWithFile(&rdb,fp);
if (rdbSaveRio(&rdb,&error) == REDIS_ERR) {
errno = error;
goto werr;
}
/* Make sure data will not remain on the OS's output buffers */
if (fflush(fp) == EOF) goto werr;
if (fsync(fileno(fp)) == -1) goto werr;
if (fclose(fp) == EOF) goto werr;
/* Use RENAME to make sure the DB file is changed atomically only
* if the generate DB file is ok. */
if (rename(tmpfile,filename) == -1) {
redisLog(REDIS_WARNING,"Error moving temp DB file on the final destination: %s", strerror(errno));
unlink(tmpfile);
return REDIS_ERR;
}
redisLog(REDIS_NOTICE,"DB saved on disk");
server.dirty = 0;
server.lastsave = time(NULL);
server.lastbgsave_status = REDIS_OK;
return REDIS_OK;
werr:
fclose(fp);
unlink(tmpfile);
redisLog(REDIS_WARNING,"Write error saving DB on disk: %s", strerror(errno));
return REDIS_ERR;
}
If you're using C with Win32, you can leverage its Structured Exception Handling (SEH) to simulate try/catch.
If you're using C in platforms that don't support setjmp() and longjmp(), have a look at this Exception Handling of pjsip library, it does provide its own implementation
After studying the answers given above, I set up a system that automatically handles nested exceptions well. Here is the code I wrote to test my system:
#include "MyOtherTricks.h"
#include "Exceptions.h"
void Testing_InnerMethod();
void Testing_PossibleExceptionThrower();
void TestExceptionHandling()
{
try
{
Testing_InnerMethod();
Say("The inner method exited without an exception.");
}
catch (Exception)
{
Say("I caught an Exception that the inner method did not catch.");
}
end_try
}
void Testing_InnerMethod()
{
try
{
Say("I am in a try block.");
Testing_PossibleExceptionThrower();
Say("The possible exception thrower didn't throw an exception.");
}
catch (ExceptionSubtype1)
Say("I caught an exception, subtype 1.");
catch (ExceptionSubtype2)
{
Say("I caught an exception, subtype 2.");
Say("I will now rethrow it.");
throw(exception);
}
end_try
}
void Testing_PossibleExceptionThrower()
{
Say("Here is the possible exception thrower.");
throw(new(ExceptionSubtype2)); // To further test exception handling, replace ExceptionSubtype2 in this line with Exception or ExceptionSubtype1, or comment out this line entirely.
Say("No, I won't throw an exception!");
}
The example code relies on two files, Exceptions.h and Exceptions.c. Here is Exceptions.h:
#include <setjmp.h>
extern jmp_buf* Exception_Handler;
#define try do \
{ \
jmp_buf* outerExceptionHandler = Exception_Handler; \
jmp_buf exceptionHandler; \
Exception_Handler = &exceptionHandler; \
Exception exception = (Exception)setjmp(exceptionHandler); \
if (exception != 0) Exception_Handler = outerExceptionHandler; \
if (exception == 0) \
{ \
// The try block goes here. It must not include a return statement or anything else that exits the try...end_try block, because then the outer exception handler will not be restored.
#define catch(exceptionType) Exception_Handler = outerExceptionHandler; \
} \
else if (Object_IsSomeTypeOf(exception, exceptionType)) \
{
// The catch block goes here. It may include a return statement or anything else that exits the try...end_try block. A break statement will exit only the try...end_try block.
#define end_try } \
else \
throw(exception); \
} while(0);
void throw(Exception exception);
And here is Exceptions.c:
#include "MyOtherTricks.h"
#include "Exceptions.h"
jmp_buf* Exception_Handler = 0;
void throw(Exception exception)
{
if (Exception_Handler == 0) FailBecause("Uncaught exception.");
longjmp(*Exception_Handler, (int)exception);
}
Note that this code references some additional methods that I'm not including here (because class inheritance in C is off-topic). To make this code work for you, you'll have to understand this code well enough to replace a few things. In particular, if you want to distinguish between different types of exceptions, you'll need to realize that this code assumes that Object_IsSomeTypeOf(new(ExceptionSubtype1), Exception) returns true and Object_IsSomeTypeOf(new(ExceptionSubtype1), ExceptionSubtype2) returns false, and you'll need to either make your own version of my Object_IsSomeTypeOf macro or replace it with something else.
Perhaps not a major language (unfortunately), but in APL, theres the ⎕EA operation (stand for Execute Alternate).
Usage:
'Y' ⎕EA 'X'
where X and Y are either code snippets supplied as strings or function names.
If X runs into an error, Y (usually error-handling) will be executed instead.

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.
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;
}
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();
}
What are you doing in the else statements? If nothing, try this:
int err = func1(...);
if (err) {
return err;
}
err = func2(...);
if (err) {
return err;
}
err = func3(...);
return err;
This way you're short-circuiting the entire function, not even bothering with the following function calls.
EDIT
Going back and reading again, I realize that it doesn't matter what you do in your else statements. That sort of code can easily go immediately after the if blocks.
If error codes are boolean, then try the simpler code below:
return func1() && func2() && func3()
One approach which has been taken by OpenGL is to not return errors from functions at all but rather present an error state which can be examined after the function call. One nice thing about this approach is that when you have a function which you actually want to return something other than an error code, you can handle errors in the same way. Another thing which is nice about this is that if a user wants to call a number of functions and only succeed if all of them were successful, you can check for errors after the x amount of calls.
/* call a number of functions which may error.. */
glMatrixMode(GL_MODELVIEW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
/* ...check for errors */
if ((error = glGetError()) != GL_NO_ERROR) {
if (error == GL_INVALID_VALUE)
printf("error: invalid value creating view");
else if (error == GL_INVALID_OPERATION)
printf("error: invalid operation creating view");
else if (error == GL_OUT_OF_MEMORY)
printf("error: out of memory creating view");
}
Others have suggested good ideas. Here're the idioms I've seen
int err;
...
err = foo(...);
if (err)
return err;
...
You could macro this out to something like
#define dERR int err=0
#define CALL err =
#define CHECK do { if (err) return err } while(0)
...
void my_func(void) {
dERR;
...
CALL foo(...);
CHECK;
or, if you're feeling really motivated, fiddle with CALL and CHECK so they can be used like
CALL foo(...) CHECK;
or
CALL( foo(...) );
--
Often, functions which need to do cleanup on exit (e.g. free memory) are written like this:
int do_something_complicated(...) {
...
err = first_thing();
if (err)
goto err_out;
buffer = malloc(...);
if (buffer == NULL)
goto err_out
err = another_complicated(...);
if (err)
goto err_out_free;
...
err_out_free:
free(buffer);
err_out:
return err; /* err might be zero */
}
You could use that pattern, or try to simplify it with macros.
--
Finally, if you're feeling /really/ motivated, you can use setjmp/longjmp.
int main(int argc, char *argv[]) {
jmp_buf on_error;
int err;
if (err = setjmp(on_error)) {
/* error occurred, error code in err */
return 1;
} else {
actual_code(..., on_error);
return 0;
}
}
void actual_code(..., jmp_buf on_error) {
...
if (err)
longjmp(on_error, err);
}
Essentially, a declaration of a new jmp_buf and a setjmp function as setting up a try block. The case where setjmp returns non-zero is your catch, and calling longjmp is your throw. I wrote this with passing the jmp_buf around in case you want nested handlers (e.g. if you need to free stuff before signaling an error); if you don't need that, feel free to declare err and the jmp_buf as globals.
Alternately, you could use macros to simply the argument passing around. I'd suggest the way Perl's implementation does it:
#define pERR jmp_buf _err_handler
#define aERR _err_handler
#define HANDLE_ERRORS do { jmp_buf _err_handler; int err = setjmp(_err_handler);
#define END_HANDLE while(0)
#define TRY if (! err)
#define CATCH else
#define THROW(e) longjmp(_err_handler, e)
void always_fails(pERR, int other_arg) {
THROW(42);
}
void does_some_stuff(pERR) {
normal_call(aERR);
HANDLE_ERRORS
TRY {
always_fails(aERR, 23);
} CATCH {
/* err is 42 */
}
END_HANDLE;
}
int main(int argc, char *argv[]) {
HANDLE_ERRORS
TRY {
does_some_stuff(aERR);
return 0;
} CATCH {
return err;
}
DONE_ERRORS;
}
--
Phew. I'm done. (Crazy examples untested. Some details might be off.)
And now for something completely different...
Another approach is to use a struct to contain your error information, e.g:
struct ErrorInfo
{
int errorCode;
char *errorMessage;
#if DEBUG
char *functionName;
int lineNumber;
#endif
}
The best way to use this is to return your method's results as the return code (e.g. "FALSE for failed", or "a file pointer or NULL if it fails", or "size of the buffer or 0 if it fails", etc) and pass in an ErrorInfo as a parameter that the called function will fill in if something fails.
This gives rich error reporting: if the method fails, you can fill in more than a simple error code (e.g. error message, code line and file of the failure, or whatever). The nice thing about it being a struct is that if you think of something, anything, useful later, you can just add it - for example, in my struct above I've allowed for a debug build to include the location of the error (file/line), but you could add a dump of the whole call stack in there at any time without having to change any of the client code.
You can use a global function to fill in an ErrorInfo so the error return can be managed cleanly, and you can update the struct to provide more info easily:
if (error)
{
Error(pErrorInfo, 123, "It failed");
return(FALSE);
}
...and you can have variants of this function that return FALSE, 0, or NULL, to allow most error returns to be phrased as a single line:
if (error)
return(ErrorNull(pErrorInfo, 123, "It failed"));
This gives you a lot of the advantages of an Exception class in other languages (although the caller still needs to handle the errors - callers have to check for error codes and may have to return early, but they can do nothing or next-to-nothing and allow the error to propagate back up a chain of calling methods until one of them wishes to handle it, much like an exception.
In addition, you can go further, to create a chain of error reports (like "InnerException"s):
struct ErrorInfo
{
int errorCode;
char *errorMessage;
...
ErrorInfo *pInnerError; // Pointer to previous error that may have led to this one
}
Then, if you "catch" an error from a function that you call, you can create a new, higher-level error description, and return a chain of these errors. e.g. "Mouse speed will revert to the default value" (because) "Preference block 'MousePrefs' could not be located" (because) "XML reader failed" (because) "File not found".
i.e.
FILE *OpenFile(char *filename, ErrorInfo *pErrorInfo)
{
FILE *fp = fopen(filename, "rb");
if (fp == NULL)
return(ChainedErrorNull(pErrorInfo, "Couldn't open file"));
return(fp);
}
XmlElement *ReadPreferenceXml(ErrorInfo *pErrorInfo)
{
if (OpenFile("prefs.xml", pErrorInfo) == NULL)
return(ChainedErrorNull(pErrorInfo, "Couldn't read pref"));
...
}
char *ReadPreference(char *prefName, ErrorInfo *pErrorInfo)
{
XmlElement *pXml = ReadPreferenceXml(pErrorInfo);
if (pXml == NULL)
return(ChainedErrorNull(pErrorInfo, "Couldn't read pref"));
...
}
You should check out what DirectX has done with the HRESULT - it's basically this. There's a reason that the exception came into being. Alternatively, if you run on Win32, they have SEH which runs in C programs.
You can get really silly and do continuations:
void step_1(int a, int b, int c, void (*step_2)(int), void (*err)(void *) ) {
if (!c) {
err("c was 0");
} else {
int r = a + b/c;
step_2(r);
}
}
This probably isn't actually what you want to do, but it is how many functional programming languages are used, and even more often how they model their code for optimization.
Something I've recently seen is this idom:
int err;
do
{
err = func1 (...);
if (!err) break;
err = func2 (...);
if (!err) break;
err = func3 (...);
if (!err) break;
/* add more calls here */
} while (0);
if (err)
{
/* handle the error here */
return E_ERROR; /* or something else */
}
else
{
return E_SUCCESS;
}
Pro arguments:
It avoids the goto (abuses the while(0) / break combination for that). Why would you want to do this? It keeps the cyclomatic complexity down and will still pass most static code analyzer checks (MISRA anyone?). For projects that get tested against cyclomatic complexity this is a god sent because it keeps all the initialization stuff together.
Contra arguments:
The meaning of the do/while loop construct is not obvious because a loop-construct is used as a cheap goto replacement, and this can only be seen at the loop tail. I'm sure for the first time this construct will cause lots of "WTF"-moments.
At least a comment is necessary to explain why the code is written the way it is required.
Here's a quite informative article & test file by IBM Unix article series:
Errors: errno in UNIX programs
Working with the standard error mechanism
https://www.ibm.com/developerworks/aix/library/au-errnovariable/
Another good example of how to implement exit codes is the source code of curl (man 1 curl).
Provided you are working with a specific context, I think the following pattern is very nice. The basic idea is that operations on an error-set state are no-ops, so error checking can be postponed to when it is convenient!
A concrete example: A deserialization context. Decoding of any element can fail, but the function may continue without error checking because all the decode_* functions are no-ops when the serialization record is in an error state. It's a matter of convenience or opportunity or optimization to insert decode_has_error. In the example below, there is no error check, the caller will take care of that.
void list_decode(struct serialization_record *rec,
struct list *list,
void *(*child_decode)(struct serialization_record *)) {
uint32_t length;
decode_begin(rec, TAG);
decode_uint32(rec, &length);
for (uint32_t i = 0; i < length; i++) {
list_append(list, child_decode(rec));
}
decode_end(rec, TAG);
}

printing on screen and a text file

I need to dump the certain things into a text file and same has needs to be displayed on screen. (I'm telling about a C program utiltiy)
The menu option looks like following,
1. display AA parameters
2. display BB parameters
3. display CC parameters
4. dump all
5. Exit
Select option >
If they select 1/2/3, it just needs to displayed on screen only or if they select option #4,it need to display all the parameters one by one and same needs to dumped in a .txt file.
I know, we can use the printf and fprintf functions to display on screen and write it to text file respectively. The thing is that I've display more that 20 parameters and each have at least 20 sub-parameters.
I'm currently implemented as below,
printf ( "Starting serial number [%ld]\n",
serial_info_p->start_int_idx);
fprintf(file_p, "Starting serial number [%ld]\n",
serial_info_p->start_int_idx)
printf ( "Current Serial number [%d]\n",
serial_info_p->current_int_idx);
fprintf(file_p, "Current Serial number [%d]\n",
serial_info_p->current_int_idx);
Is there an easiest way to implement this to cut down the number of lines of code?
Edit: the C++ tag seems misleading, can someone remove it please? thanks :)
I use variadic macros to customize printf and friends.
I would write something like this:
#define tee(fp,fmt, ...) \
{ \
printf (fmt, __VA_ARGS__); \
fprintf (fp, fmt, __VA_ARGS__); \
}
(the name comes from the tee(1) utility)
Something like this allows you to add any number of output streams, and allows changing them at runtime simply by modifying the PrintTarget linked list.
/** gcc -Wall -o print_target print_target.c && ./print_target */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct PrintTarget* PrintTargetp;
void* xmalloc (size_t size);
PrintTargetp pntCreate (PrintTargetp head, FILE* target);
void pntDestroy (PrintTargetp list);
typedef struct PrintTarget
{
FILE* target;
PrintTargetp next;
} PrintTarget;
void myPrintf (PrintTargetp streams, char* format, ...)
{
va_list args;
va_start(args, format);
while (streams)
{
vfprintf(streams->target, format, args);
streams = streams->next;
}
va_end(args);
}
int main(void)
{
PrintTargetp streams = pntCreate(NULL, stdout);
streams = pntCreate(streams, fopen("somefile.txt", "a+")); //XXX IO errors?
myPrintf(streams, "blah blah blah...\n");
pntDestroy(streams);
return 0;
}
Here's a definition of auxiliary functions:
PrintTargetp pntCreate (PrintTargetp head, FILE* target)
{
PrintTargetp node = xmalloc(sizeof(PrintTarget));
node->target = target;
node->next = head;
return node;
}
void pntDestroy (PrintTargetp list)
{
while (list)
{
PrintTargetp next = list->next;
free(list);
list = next;
//XXX cycles?
//XXX close files?
}
}
void* xmalloc (size_t size)
{
void* p = malloc(size);
if (p == NULL)
{
fputs("malloc error\n", stderr);
abort();
}
return p;
}
You could also just pipe the output of your prorgam to the tee(1) command.
If you're writing a console application, you should be able to output to the screen (standard output) using something like:
fprintf(stdout, "Hello World\n");
This should enable you to move the code that prints your data to its own function, and to pass in a FILE* for it to print to. Then the function can print to the screen if you pass "stdout", or to a file if you pass in a different FILE*, e.g.:
void print_my_stuff(FILE* file) {
fprintf( file,"Starting serial number [%ld]\n", serial_info_p->start_int_idx);
fprintf(file, "Current Serial number [%d]\n", serial_info_p->current_int_idx);
.
.
.
}
Edit: I didn't notice you needed a C solution. I'll leave this answer for reference, but it obviously requires C++.
You could create a new stream class that sends the output to two streams. I found an implementation of this at http://www.cs.technion.ac.il/~imaman/programs/teestream.html. I haven't tried it, but it should work.
Here's the code from the link:
#include <iostream>
#include <fstream>
template<typename Elem, typename Traits = std::char_traits<Elem> >
struct basic_TeeStream : std::basic_ostream<Elem,Traits>
{
typedef std::basic_ostream<Elem,Traits> SuperType;
basic_TeeStream(std::ostream& o1, std::ostream& o2)
: SuperType(o1.rdbuf()), o1_(o1), o2_(o2) { }
basic_TeeStream& operator<<(SuperType& (__cdecl *manip)(SuperType& ))
{
o1_ << manip;
o2_ << manip;
return *this;
}
template<typename T>
basic_TeeStream& operator<<(const T& t)
{
o1_ << t;
o2_ << t;
return *this;
}
private:
std::ostream& o1_;
std::ostream& o2_;
};
typedef basic_TeeStream<char> TeeStream;
You would use it like this:
ofstream f("stackoverflow.txt");
TeeStream ts(std::cout, f);
ts << "Jon Skeet" << std::endl; // "Jon Skeet" is sent to TWO streams
I'd go more radical than what people have suggested so far, but maybe it is too much for you. (The 'inline' keyword is C99; you can omit it without much consequence if you code to C89.)
/*
** These could be omitted - unless you get still more radical and create
** the format strings at run-time, so you can adapt the %-24s to the
** longest tag you actually have. Plus, with the strings all here, when
** you change the length from 24 to 30, you are less likely to overlook one!
*/
static const char fmt_int[] = "%-24s [%d]\n";
static const char fmt_long[] = "%-24s [%ld]\n";
static const char fmt_str[] = "%-24s [%s]\n"; /* Plausible extra ... */
static inline void print_long(FILE *fp, const char *tag, long value)
{
fprintf(fp, fmt_long, tag, value);
}
static inline void print_int(FILE *fp, const char *tag, int value)
{
fprintf(fp, fmt_int, tag, value);
}
static inline void print_str(FILE *fp, const char *tag, const char *value)
{
fprintf(fp, fmt_str, tag, value);
}
static void dump_data(FILE *fp, const serial_info_t *info)
{
dump_long("Starting serial number", info->start_int_idx);
dump_int( "Current Serial number", info->current_int_idx);
/* ... and similar ... */
}
Then the calling code would call dump_data() once (with argument stdout) for options 1, 2, 3 and twice (once with stdout, once with file pointer for output file) for option 4.
If the number of parameters got truly huge (into the multiple hundreds), I'd even go as far as to consider a data structure which encoded type and offset information (offsetof from <stddef.h>) and pointers to functions and such like, so that there would be just a loop in dump_data() iterating over a structure which encodes all the necessary information.
You could also simplify life by using the same basic integer type (long in your example) for all the integer members of the data structure.
Fred Brooks in "Mythical Man Month" - a book well worth reading if you've not already done so, but make sure you read the Twentieth Anniversary edition - says in Chapter 9:
Show me your flowcharts [code] and conceal your tables [data structures], and I shall continue to be mystified. Show me your tables, and I won't usually need your flowcharts; they'll be obvious.
A table-driven version of this code could end up saving space, as well as frustration when having to change a hundred related functions in the same way whereas a simple change in the tabular data could have fixed the whole lot.
#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))
FILE *f = fopen("somefile.txt", "a+");
FILE *fp[] = { stdout, f };
int i = 0;
for (i = 0; i < ARRAY_LEN(fp); i++) {
fprintf(fp[i], "Starting serial number [%ld]\n", serial_info_p->start_int_idx);
fprintf(fp[i], "Current serial number [%ld]\n", serial_info_p->start_int_idx);
}
fclose(f);

Resources