Messages in this thread | | | Date | Tue, 23 Jul 2002 12:49:56 +0200 (MET DST) | From | Mikael Pettersson <> | Subject | Re: [PATCH] 2.4.19-rc2-ac2 pdc202xx.c update |
| |
On Tue, 23 Jul 2002 09:19:15 +0200, Francois Romieu wrote: >support <support@promise.com.tw> : >> We think there is no problems, Acturally it is >> >> if (speed == XFER_UDMA_2) { >> OUT_BYTE((thold + adj), indexreg); >> OUT_BYTE((IN_BYTE(datareg) & 0x7f), datareg); >> } >> >> So, >> if (speed == XFER_UDMA_2) >> set_2regs(thold, (IN_BYTE(datareg) & 0x7f));
The problem is a common one for complex statement-like macros. You have a macro M consisting of (in this case) two statements S1 and S2: "#define M S1; S2". Now consider what happens when M is used in non-block context, i.e. not as a top-level statement between { and } but rather in e.g. the true branch of an if-statement:
if (condition) M;
which after preprocessing becomes
if (condition) S1; S2;
However, indentation doesn't matter, only grouping does, so this USE of the macro really is
if (condition) S1; S2;
Now do you see? The macro body was broken up, and the second statement is now executed unconditionally.
The traditional approach is to write the body of a complex macro as a do { ... } while(0) statement (i.e. #define M do { S1; S2; } while(0)) since this turns the macro body into a single unbreakable statement which is safe to use in any context where a statement may occur.
Simply wrapping the macro body with a pair of braces { } doesn't work in all contexts; the do{...}while(0) idiom does.
/Mikael - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |