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

Thursday, May 22, 2008

BlockBuster Museum

The painful life before the Internet

Thursday, May 15, 2008

Back to Basics: Part 2

As you've problably guessed, the problem is if the macro is used in if-statements. Consider this:

if(bla)
LOCK_CALL(library_func(libref, bla));
else
do_something_else();


This will be translated in to:
if(bla)
{lock(libref); library_func(libref, bla); unlock(libref);};
else
do_something_else();


See that last ';' on the macro line? That means that we have two statements on that line; the lock statement and the empty ';'. Hence this is not syntactically correct C as if you have more than one statement after an if-statement it should be in it's own block, like:

if(bla)
{
{lock(libref); library_func(libref, bla); unlock(libref);}
;
}
else
do_something_else();


How do we solve this? The do-while(0) trick to the rescue!

#define LOCK_CALL2(func) do {lock(libref); func; unlock(libref);} while(0)


This will be translated in to syntactically correct C both when used by itself and when used in an if-statement.

By now readers with attention to detail have found another flaw. "How about", they say, "if the function returns a value that you are interested in, then it won't work, Mr Smarty Pants". Well, they are correct, but there is an easy fix that solves at least part of the problem.

#define LOCK_CALL3(ret, func) do {lock(libref); ret = func; unlock(libref);} while(0)

int library_func(LIB* libref)

int ret_val;
LOCK_CALL3(ret_val, library_func));
// Now ret_val contains the return value


The only thing missing now is being able to call the function we want to lock from within an if-statement or such as the conditional,e.g.

if(LOCK_CALL(library_func(libref)))
do_stuff();
else
do_something_else();


That is left as an exercise to the reader. (In other words, I don't know how to do it!)

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?

Wednesday, May 07, 2008

Life, Not Death

Interesting interview with Peter Thiel on Reason.com. I especially like his view on life and death:
Every myth on this planet tells us the purpose of life is death, and I don’t think that’s true. I think the purpose of life is life.

Tuesday, May 06, 2008

No Control

I've only had absinthe once and I must say it was quite an enjoyable, even though not very mind-expanding, experience. No real psychedelic effects, just good clean fun. Now scientists have found that even the original "real" absinthe does not contain any psychedelic ingredients, just really strong alcohol.