error handling in C

I started writing a set of error handler macros for C, based on “Zed’s Awesome Debug Macros”

The implementation is quite ugly, and depends on a couple of GNU extensions.  This is not ideal, and I would like to improve it if possible.

https://github.com/sswam/kisskit/blob/master/kiss.h

The idea is to call functions via “wrapper macros”, which take care of checking for errors.  Here’s an example:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "kiss.h"

int main(void)
{
	char *space = NULL;
	FILE *fp = NULL;
	INFO("Hello");
	space = MALLOC(1000);
	space = REALLOC(space, 10000);
	fp = FOPEN("asdfasdf", "r");
	FCLOSE(fp);
	FREE(space);
	INFO("Bye");
	exit(0);
error:
	exit(1);
}

Output when I run it:

[INFO]  test1.c:11 main: Hello
[ERROR] test1.c:14 main: fopen failed: asdfasdf: No such file or directory

Output when I build it with -DNDEBUG and run it:

Hello
fopen failed: asdfasdf: No such file or directory

In most cases, I can add a wrapper macro with one short line of code:

#define MALLOC(...) CHK(malloc, __VA_ARGS__)
#define REALLOC(...) CHK(realloc, __VA_ARGS__)
#define FREE(ptr) (free(ptr), ptr = NULL)

#define FOPEN(path, mode) ({ char *p = path; FILE *rv = fopen(p, mode); CHECK(rv, "fopen failed: %s", p); rv; })
#define FCLOSE(fp) (ZERO(fclose, fp), fp = NULL)

The FOPEN macro is longer. I added the file name to the error message.

FREE is not checking for errors. It sets the pointer to NULL after the free. FCLOSE checks for errors and sets the FILE * to NULL.

I also wrote wrappers for some SDL and SDL_image functions, just a few so far.

Here is a short SDL example using the macros:

https://github.com/sswam/kisskit/blob/master/test.c

and the equivalent code without the macros, which is much longer:

https://github.com/sswam/kisskit/blob/master/test_plain.c

I’m in two minds about this. On the one hand, I think these wrappers can make C code shorter, safer, more readable, and more maintainable. On the other hand, it might be best to avoid macros, the implementation is ugly, and it uses two GNU extensions: ##__VA_ARGS__, and ({ statement expressions }).

Please let me know what you think. (Without being too scathing, please… I respond better to kindness!)

This entry was posted in Uncategorized. Bookmark the permalink.

3 Responses to error handling in C

  1. Prudhvi says:

    Sam, This is why i keep reading your blog. Keep them coming 🙂

  2. sswam says:

    I’ve coded about half of Lazy Foo’s SDL lessons in this style with some variations https://github.com/sswam/kisskit/tree/master/sdl … and I’m still not sure whether I like it or not… It’s difficult to decide, perhaps I should use the traditional `if (!foo()) goto error;`. I guess maybe less than 10% of an normal program is calls to library functions that can return error codes, so it’s probably doesn’t matter that much if we have lots of error-handling boilerplate. But I guess I’ll continue with these crazy gcc-extension-depending macros for the moment. (it works in clang too)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s