FAQ: #define ... do { ... } while(0)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Comments on question "Why do a lot of #defines in the kernel use do { ... }
while(0)?" in the FAQ:

IMHO the important point of the question is missing. As both Miller and
Collins point out, you want a block statement so you can have several lines
of code and declare local variables. But then the natural thing would be to
just use for example

  #define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }

However that wouldn't work in some cases. The following code is meant to be
an if-statement with two branches:

  if(x>y)
    exch(x,y);          // Branch 1
  else
    do_something();	// Branch 2

but it would be interpreted as an if-statement with only one branch. :

  if(x>y) {			// Single-branch if-statement!!!
    int tmp;		// The one and only branch consists
    tmp = x;		// of the block.
    x = y;
    y = tmp;
  }
  ;				// empty statement
  else			// ERROR!!! "parse error before else"
    do_something();

The problem is the semi-colon (;) coming directly after the block.

The solution for this is to sandwich the block between "do" and "while(0)".
Then we have a single statement with the capabilities of a block, but not
considered as being a block statement by the compiler.

Our if-statement now becomes:

  if(x>y)
    do {
      int tmp;
      tmp = x;
      x = y;
      y = tmp;
    } while(0);
  else
    do_something();


Sincerely,
Per Persson
per.persson@gnosjo.pp.se

-
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
IRC Channel:   irc.openprojects.net / #kernelnewbies
Web Page:      http://www.kernelnewbies.org/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux