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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to