svn commit: r224721 - head/sys/sys
Bruce Evans
brde at optusnet.com.au
Wed Aug 10 13:37:38 UTC 2011
On Wed, 10 Aug 2011, Alexander Best wrote:
> On Tue Aug 9 11, Bruce Evans wrote:
>> ...
>> What is wrong with the existing APIs TIMEVAL_TO_TIMESPEC() and
>> TIMESPEC_TO_TIMEVAL(), which are used for these conversions by almost
>> everything now? Well, quite a bit is wrong with them, starting with
>> ...
>
> any reason {TIMEVAL,TIMESPEC}_TO_{TIMESPEC,TIMEVAL}()s code is being executed
> in a
>
> do { ... } while (0)
>
> conditional loop?
Just the usual syntactical trick for making large macros that look
like function calls almost usable like function calls. Without the
do-while trick, code like
if (foo)
TIMEVAL_TO_TIMESPEC(&tv, &ts);
would be fragile at best. With an else clause added to it, it would expand
to either
if (foo)
first_statement_of_macro;
second_statement_of_macro; ;
else
...
which is obviously broken (3 statements between the 'if' and the 'else'
give a syntax error). We partially fix this by putting outer braces in
the macro:
if (foo)
/*
* Here I attempt to duplicate the ugly indentation,
* that tends to be preserved on expansion, which is
* given by style bugs in the macro definition. See
* sys/queue.h for similar definitions without these
* style bugs.
*/
{
first_statement_of_macro;
second_statement_of_macro;
} ;
else
...
This might work without the else clause, but with the else clause it
is still a syntax error, since there are still too many statements
between the 'if' and the 'else' -- we want to add the semicolon after
the macro invocation, since the macro invocation looks like a function
call, but this semicolon gives an extra statement and thus defeats the
reduction to a single statement in the macro be using braces.
With the trick, and without the style bugs, the above expands to:
if (foo)
do {
first_statement_of_macro;
second_statement_of_macro;
} while (0) ;
else
...
Now there is only 1 statement between the 'if' and the 'else', since we
trickily made the macro a non-statement that works after adding a semicolon
to it -- the semicolon completes the statement, and the do-while is a
trick that works (I don't know of any other).
> both macros are also defined in crypto/openssh/defines.h and
> don't seem to need that extra one-time-loop.
Macros that are only used locally can be sloppier, but shouldn't be.
Bruce
More information about the svn-src-head
mailing list