4th
MAY

Macros using do{}while(0);

Posted by Strainu | Filed under C

If you ever had the chance to look in the Linux kernel sources, you might have seen macros defined like this:

#define foo(params) \
do{ \
    //instructions \
}while(0)

This basicly means that the code is executed exactly once, so the first idea is that do{}while(0); is useless.
In fact, there are a number of reasons for writing the macros this way:

  • Empty statements give warnings from the compilers, so rather than writing
    #define FOO

    you might want to write

    #define FOO do{}while(0)
  • It gives you a basic block in which to declare local variables. You could simply use curly brackets, but this could cause serious problems in conditional statements. Let’s take the following example:
    #define exch(a,b) {int t; t = a; a = b; b = t;}

    You then use the macro in the following code:

    if(a[i]<a [i+1])
        exch(a[i],a[i+1]);
    else
        ready = 1;

    This is what the copiler will get:

    if(a[i]<a [i+1]){
        int t;
        t = a[i];
        a[i] = a[i+1];
        a[i+1] = t;
    };
    else
        ready = 1;

    This is interpreted as an if statement whithout else and you will get an error like “else without matching if”. However, if you write the macro like this:

    #define exch(a,b) do{int t; t = a; a = b; b = t;}while(0)

    the code will behave as expected.

You can find more informations about this in the Kernelnewbies FAQ.

Share and Enjoy:
  • Facebook
  • Twitter
  • Identi.ca
  • email
  • Add to favorites
  • Digg
  • StumbleUpon

Tags: ,

Reader's Comments

  1. CoderTricks » Blog Archive » Simple debugging in kernel programming |

    [...] You can use the same code in userspace programs by replacing printk with printf. And just in case you’re wondering what’s with the empty do-while, you might want to take a look at this older article. [...]

  2. gridorian |

    ::CODECOLORER_BLOCK_8::
    ;) no more int t;

  3. Strainu |

    True. However, this wasn`t really the point of the program :) Besides that, your code has a small overflow problem :) Say a = b = 3.000.000.000 … Then a+b will give you an overflow. An alternative solution might be:

    ::CODECOLORER_BLOCK_9::

Leave a Reply