Re: [PATCH] genirq: ARM dyntick cleanup

From: Randy.Dunlap
Date: Wed Jul 05 2006 - 19:58:35 EST


On Wed, 5 Jul 2006 16:53:22 -0700 (PDT) Linus Torvalds wrote:

>
>
> On Wed, 5 Jul 2006, Randy.Dunlap wrote:
> >
> > OK, I'll bite. What part of Linus's macro doesn't work.
>
> Heh. This is "C language 101".

Yes, I got most of that. :)
more below.

> The reason we always write
>
> #define empty_statement do { } while (0)
>
> instead of
>
> #define empty_statement /* empty */
>
> is not that
>
> if (x)
> empty_statement;
>
> wouldn't work like Arjan claimed, but because otherwise the empty
> statement won't parse perfectly as a real C statement.
>
> In particular, you tend to get much better error messages if you have
> syntax errors _around_ the empty statement if it's done as that
> "do { } while (0)" thing. You also avoid compiler warnings about
> empty statements or statements without effects, that you'd get if you were
> to use
>
> #define empty_statement /* empty */
>
> or
>
> #define empty_statement 0
>
> for example (a expression statement is a perfectly valid statement, as is
> an empty one, but many compilers will warn on them).
>
> It's also simply good practice - if you _always_ do the "do { } while (0)"
> thing, you'll never get bitten by having a macro that has several
> statements inside of it, and you'll also never get bitten by a macro that
> is _meant_ to be used as a statement being used as part of an expression
> instead.
>
> It basically boils down to the fact that the "do { } while (0)" format is
> always syntactically correct, /regardless/ of what is inside of the
> braces, and should always give you meaningful error messages regardless of
> what is _around_ the macro usage.

Yes, I already understood that. I was interested in Arjan's
specific example, which was:

if (foo())
zyzzy();

in which he supplied the terminating semi-colon, and which Andrew
explained with the -W warning...

> For example:
>
> if (a)
> empty_statement
> b;
>
> will give the _correct_ syntax error message ("expected ';'"), instead of
> silently turning into
>
> if (a)
> b;
>
> or other nonsense.

OK, good practice, yes.

> But in the end, the real aim is to just teach your fingers to _always_ put
> the do/while(0) there, so that you never EVER write something like
>
> #define MACRO one; two;
>
> which really breaks down.
>
> This is, btw, the same reason a lot of people (including me, most of the
> time) will write
>
> #define VALUE (12)
>
> instead of writing the simpler
>
> #define VALUE 12
>
> just because it's good practice to _always_ have the parentheses around
> a macro that ends up being used as an expression.
>
> So we always also write
>
> #define ADD(a,b) ((a)+(b))
>
> because otherwise you eventually _will_ get bitten (we've had that
> particular bug bite us in the *ss lots of times, even though people should
> know better)

Yes, I have the () macro practice down. I was just looking for the
problem with that one specific example, which you and Andrew have now
explained. Thanks.

---
~Randy
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/