Home > Programming > The essence of do{ } while(0)

The essence of do{ } while(0)

This is something that I’ve been longing to document in my blog. Many times I have wondered why almost all the #define macros in linux kernel is made up of do-while blocks rather than simple {} blocks. The reason is illustrated below:

Consider for example a swap() macro defined in the two different ways as shown below:

#define swap(a,b) { \

typeof(a) tmp; \

tmp=a; a=b; b=tmp; \

}

and

#define swap(a,b) do { \

typeof(a) tmp; \

tmp=a;a=b;b=tmp; \

} while(0)

At a glance both seem to do the same job of creating a new block of code where the variable tmp is created and the values a and b are swapped through it. And they both will work similarly under all circumstances except the following:

if(a<b)

swap(a,b);

else

printf("a is already greater than b\n");

The above code when using the first form of swap() macro will expand as following:

if(a<b)

{

typeof(a) tmp;

tmp=a;a=b;b=tmp;

}

;

else

printf("a is already greater than b\n");

The issue here is that the semicolon (;) that we have put after swap() infact terminates the if block and remains as an empty statement. This causes the else keyword not to be attached to the if block anymore and will cause a compilation error saying that the else keyword is misplaced. huh !

Anyway, good that we got a workaround for this problem, otherwise writing system software would have become a hell :-D . By the way, if you are using gcc, you can use ({ }) blocks as well which would be very much helpful if your macro needs to return some value ;-) – the return value is the last evaluated expression.

Categories: Programming
  1. No comments yet.
  1. No trackbacks yet.

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 )

Connecting to %s

Follow

Get every new post delivered to your Inbox.