svn commit: r224721 - head/sys/sys

Alexander Best arundel at freebsd.org
Wed Aug 10 15:49:56 UTC 2011


On Wed Aug 10 11, Bruce Evans wrote:
> 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.

thanks a lot for the in depth information. :) any reason, back in the days, it
was decided that the functionality of converting a timespec to a timeval and
vice versa should be implemented as a macro and not a function?

cheers.
alex

> 
> Bruce


More information about the svn-src-head mailing list