From 630d9305b266dcf14f216513c461fa9f66e798a3 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 3 Aug 2019 20:07:08 +0100 Subject: [PATCH] doc/runtime.tex, lib/keyword.3: Explain the other benefit of `NO_KWARGS'. It's not just for hacking around C89 after all. --- doc/runtime.tex | 31 +++++++++++++++++++++++++------ lib/keyword.3 | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/doc/runtime.tex b/doc/runtime.tex index 7ca8cbd..e22ed59 100644 --- a/doc/runtime.tex +++ b/doc/runtime.tex @@ -142,18 +142,37 @@ lists. Their use is not essential, but may help prevent errors. argument consists of a sequence of calls to the keyword-argument macros described below, one after another without any separation. - In C89, macro actual arguments are not permitted to be empty; if there are - no keyword arguments to provide, and you're using a C89 compiler, then use - @|NO_KWARGS| (below) instead. If your compiler supports C99 or later, it's - fine to just write @|KWARGS()| instead. + If there are no keyword arguments, use @|NO_KWARGS| (below) instead. \end{describe} \begin{describe}{mac}{NO_KWARGS} A marker, to be written instead of a @|KWARGS| invocation, to indicate that no keyword arguments are to be passed to a function. - This is unnecessary with compilers which support C99 or later, since once - can use @|KWARGS()| with an empty @ argument. + Using this macro instead of @|KWARGS| if there are no arguments does two + things: + \begin{itemize} + + \item C89 doesn't permit empty macro arguments for some reason, so + @|NO_KWARGS| is necessary when using a C89 compiler. + + \item Omitting the null terminator is a common mistake, so @|| + tries to get the compiler to warn if you miss it. However, the + \descref{KWTAIL}[macro]{mac} introduces an extra real argument + @|kwfirst_|, because it's not possible to scan a variable-length argument + tail if there are no mandatory arguments. If you use @|KWARGS()|, with + an empty argument list, then the null terminator is passed as @|kwfirst_| + and the variable-length tail ends up empty, which might trigger a + compiler warning about the missing terminator. @|NO_KWARGS| passes + \emph{two} null terminators: a real one to indicate that there are no + keyword arguments, and a dummy one to placate the compiler. + + (Sod method entry functions don't have this extra argument, so + @|KWARGS()| would work fine for sending Sod messages with keyword + arguments if you're using C99 or later, but it's probably best to use the + version which always works.) + + \end{itemize} \end{describe} The following keyword-argument macros can be used within the @|KWARGS| diff --git a/lib/keyword.3 b/lib/keyword.3 index db5b86d..7847733 100644 --- a/lib/keyword.3 +++ b/lib/keyword.3 @@ -402,15 +402,41 @@ argument consists of a sequence of calls to the keyword-argument macros described below, one after another without any separation. .PP -In C89, macro actual arguments are not permitted to be empty; -if there are no keyword arguments to provide, -then the argument-less macro +If there are no keyword arguments, +use the argument-less macro .B NO_KWARGS -should be used instead. -If you're using C99 or later, -it's fine to just write -.B KWARGS() instead. +There are two reasons for this. +.hP \*o +C89 doesn't permit empty macro arguments for some reason, +so +.B NO_KWARGS +is necessary when using a C89 compiler. +.hP \*o +Omitting the null terminator is a common mistake, +so +.B +tries to get the compiler to warn if you miss it. +However, the +.B KWTAIL +macro introduces an extra real argument +.BR kwfirst_ , +because it's not possible to scan a variable-length argument tail +if there are no mandatory arguments. +If you use +.BR KWARGS() , +with an empty argument list, +then the null terminator is passed as +.B kwfirst_ +and the variable-length tail ends up empty, +which might trigger a compiler warning +about the missing terminator. +.B NO_KWARGS +passes +.I two +null terminators: +a real one to indicate that there are no keyword arguments, +and a dummy one to placate the compiler. .PP The following keyword-argument macros can be used within -- 2.11.0