Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Aug 2011 23:37:35 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Alexander Best <arundel@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, Jonathan Anderson <jonathan@freebsd.org>, Bruce Evans <brde@optusnet.com.au>
Subject:   Re: svn commit: r224721 - head/sys/sys
Message-ID:  <20110810230856.M2222@besplex.bde.org>
In-Reply-To: <20110810103831.GA60858@freebsd.org>
References:  <201108082036.p78KarlR062810@svn.freebsd.org> <20110809105824.P896@besplex.bde.org> <20110810103831.GA60858@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110810230856.M2222>