In the Linux KernelCodeHas such macro definition:
# Define dump_write (ADDR, NR) do {memcpy (bufp, ADDR, NR); bufg + = nR;} while (0)
This macro definition means that the loop body will be executed once when this macro operation is referenced, but why is it defined as such a strange form?
Let's take a look at the macro definitions in several other forms:
# Define dump_write (ADDR, NR) memcpy (bufp, ADDR, NR); bufp + = nR;
Is this macro definition acceptable?
We put this macro in a context:
If (ADDR)
Dump_write (ADDR, NR );
Else
Do_something_else ();
The result shows an error occurs during compilation. Why?
Expand the macro, and the preceding statement block is changed:
If (ADDR)
Memcpy (bufp, ADDR, NR); bufp + = nR;
Else
Do_something_else ();
In this way, a statement bufp + = nR is added between the IF-else statement to form a statement similar to if-dosomething-Else. In this way, else will not be able to find the matching if, so the compiler will report an error.
Alternative reference format:
If (! ADDR)
Do_something_else ();
Else
Dump_write (ADDR, NR );
In this way, compilation is successful, but the problem is more serious, because bufp + = nR; will always be executed.
Here, we may immediately consider adding a braces in the macro definition:
# Define dump_write (ADDR, NR) {memcpy (bufp, ADDR, NR); bufp + = nR ;}
Can this work? Let's test it in context:
If (ADDR)
Dump_write (ADDR, NR );
Else
Do_something_else ();
Still compilation error. Why?
Expand the macro:
If (ADDR)
{Memcpy (bufp, ADDR, NR); bufp + = nR ;};
Else
Do_something_else ();
Here, an empty statement is inserted in the IF-else statement: If-null statement-else. The compiler cannot find the matching if statement for else. Therefore, an error will still be reported during compilation.
Using the macro definition in the following format is completely correct.
# Define dump_write (ADDR, NR) do {memcpy (bufp, ADDR, NR); bufg + = nR;} while (0)
In the Linux kernel code, the macro definition is as follows:
# Define dump_write (ADDR, NR) do {memcpy (bufp, ADDR, NR); bufg + = nR;} while (0)
This macro definition means that the loop body will be executed once when this macro operation is referenced, but why is it defined as such a strange form?
Let's take a look at the macro definitions in several other forms:
# Define dump_write (ADDR, NR) memcpy (bufp, ADDR, NR); bufp + = nR;
Is this macro definition acceptable?
We put this macro in a context:
If (ADDR)
Dump_write (ADDR, NR );
Else
Do_something_else ();
The result shows an error occurs during compilation. Why?
Expand the macro, and the preceding statement block is changed:
If (ADDR)
Memcpy (bufp, ADDR, NR); bufp + = nR;
Else
Do_something_else ();
In this way, a statement bufp + = nR is added between the IF-else statement to form a statement similar to if-dosomething-Else. In this way, else will not be able to find the matching if, so the compiler will report an error.
Alternative reference format:
If (! ADDR)
Do_something_else ();
Else
Dump_write (ADDR, NR );
In this way, compilation is successful, but the problem is more serious, because bufp + = nR; will always be executed.
Here, we may immediately consider adding a braces in the macro definition:
# Define dump_write (ADDR, NR) {memcpy (bufp, ADDR, NR); bufp + = nR ;}
Can this work? Let's test it in context:
If (ADDR)
Dump_write (ADDR, NR );
Else
Do_something_else ();
Still compilation error. Why?
Expand the macro:
If (ADDR)
{Memcpy (bufp, ADDR, NR); bufp + = nR ;};
Else
Do_something_else ();
Here, an empty statement is inserted in the IF-else statement: If-null statement-else. The compiler cannot find the matching if statement for else. Therefore, an error will still be reported during compilation.
Using the macro definition in the following format is completely correct.
# Define dump_write (ADDR, NR) do {memcpy (bufp, ADDR, NR); bufg + = nR;} while (0)