1

I have noticed a programming style in Embedded C, used for firmware programming:

#define WRITE_REGISTER(reg, value) \
        do { \
           write_to_register(reg, value); \
        } while (0)

How does this do...while (0) help over:

#define WRITE_REGISTER(reg, value) write_to_register(reg, value)
rmaddy
  • 314,917
  • 42
  • 532
  • 579
AbhinavChoudhury
  • 1,167
  • 1
  • 18
  • 38
  • This is the best thread I've found regarding the do-while macro. Hope it helps, not sure if it will. http://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-c-c-macros – Guy Kogus Dec 02 '13 at 14:07

2 Answers2

10

As you can see here the do {} while(0) permits to avoid compilation errors or bad working when there are multiple lines in the macro and you try to call the macro in the same way as a c function (which is the way everyone does).

As an example (I report the one in the link here so you don't need to navigate the page)

#define DO_SOMETHING_HERE(_x) foo(_x); bar(_x);

if( condition )
    DO_SOMETHING_HERE(_x);
else
    ...

will generate a compilation error because it will result in:

if( condition )
    foo(_x); bar(_x);;
else
    ...

Using the do while everything will work fine, infact it will be:

#define DO_SOMETHING_HERE(_x) do{ foo(_x); bar(_x); }while(0) 
if( condition )
   do{ foo(_x); bar(_x); } while(0);
else
   ...

Note that in this case putting braces will not save you because:

#define DO_SOMETHING_HERE(_x) { foo(_x); bar(_x); } 
if( condition )
   { foo(_x); bar(_x); };
else
  ...

still generates an error.

In your case I think it's only a coding style because there's one line only.

Jekyll
  • 1,434
  • 11
  • 13
1

With this kind of loop definition, you can use break statements within. This allows easier error handling. Example:

do
{
    /* A lot of code */

    if(error)
        break;

    /* A lot of code */
{
while(0)
Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46