Variable arguments in macros

Jerry Leichter LEICHTER-JERRY@CS.YALE.EDU leichter at CS.YALE.EDU
Wed Apr 26 03:16:05 AEST 1989


I proposed a way to do this - and an additional reason why it would be useful
- a long time back, but I'm not sure just where.

Here's the jist:  Extend #define so that

#define f(a,b, ...)	<whatever>

is allowed.  When used as a macro, f must have at least two arguments, but
it may have any number of additional ones.  (The syntax is intended to be
exactly like that for functions with variable numbers of arguments.)

Within the definition of a macro taking a variable number of arguments, the
fixed arguments may be used as usual.  In addition, two built-in macros are
available:  _REST_ expands to the list of remaining arguments, including a
leading comma if there is at least one such argument; and _NARGS_ expands to
the total number of arguments passed.  Thus:

#define f(a,b, ...)	g(_NARGS_,a,b _REST_)
f(1,2,3,4)	==>	g(4,1,2 ,3,4)
f(1,2)		==>	g(2,1,2 )
f(1)		==>	<error>

For consistency, _REST_ and _NARGS_ should be available in any macro expan-
sion; _REST_ will be empty, and _NARGS_ will be the count of arguments (0 for
a macro taking no arguments).

(The ugliest part of this is the need to include the leading comma in _REST_,
and then omit it using _REST_ in an argument list.  If you don't do that,
however, you have to use:

#define f(a,b, ...)	g(_NARGS_,a,b,_REST_)
f(1,2)		==>	g(2,1,2,)

which is erroneous.  Of course, we could allow extraneous comma's in function
calls (and declarators, for consistency)....)

While this makes it easy to write macros calling fprintf and such, the main
reason it is nice is that it provides a portable, efficient way to get the
effect of the old nargs() call.  It's very useful to be able to determine how
many arguments you have been called with.  For example, it allows you to
extend a function by adding additional arguments without making previous uses
stop working.  It would also allow a function like fprintf, if it chose, to
check for the sanity of the arguments it was given - it would be useful to
have a debugging version of fprintf which told you that you hadn't matched
the number of arguments and the number of specifiers.

The objection that's been raised to requiring an nargs() facility is that it
can be expensive on some architectures and most functions don't need it.  With
the macro facility I'm proposing, you can add the support yourself for exactly
those functions where it's important to you.

							-- Jerry



More information about the Comp.std.c mailing list