This is a blog about me, Seinfeld, okonomiyaki, japanese toilet seats, and other things of interest

Thursday, May 15, 2008

Back to Basics

It feels good to program in C and C++ again after spending the last few years mostly working in various dynamic languages. I definitely feel less productive in C than for example Python, but it is somehow much more fun to be closer to the machine. This also means that I have to re-discover all the tricks and idioms of C, the folklore of C, so to speak.

One classic idiom is the do-while(0) preprocessor trick. Say that you want to wrap calls to particular functions with a function call before the function and one after. A typical example is if you are calling a library that isn't thread-safe in a multi-threaded environment. Before each call you want to call lock(libref);, then the non thread-safe library_func(libref, ...);, and then finally unlock(libref);. You could of course just write:
lock(libref);
library_func(libref);
unlock(libref);

Imagine that you have hundreds of these calls and that you then change your mind and want to call two lock functions before calling library_func:. Then you have to edit the code everywhere. Not very DRY. What we would like to do is to wrap all calls using the libref so that they do whatever locking and other stuff we want.

Maybe the most obvious way to do this is to use the much loved - and hated - feature of C called the preprocessor. Something like
#define LOCK_CALL(func) {lock(libref); func; unlock(libref);}

LOCK_CALL(library_func(libref));


This looks like it will work - and it does - unless in certain contexts. Can you spot the problem?

0 Comments:

Post a Comment

<< Home