[comp.lang.c] STDARG.H

raymond@ptolemy.arc.nasa.gov (Eric A. Raymond) (04/08/89)

The variable argument facility as provided by STDARG.H (in the ANSI
standard?)  appears to have a severe limitation.  Any additional
arguments you supply in the caller are retrieved as a list of args.
Unfortunately there is no way to know when you have reached the end of
this list.

Thus if you have a function F(a,b,c, ...) and two calls to it F(1,2,3)
and F(1,2,3,4), there is really no way to know that an optional
argument was passed (or was not passed).  What I really want is
something to approximate the expressiveness/flexiblity of &optional or
&rest in Lisp.

In order to make this work, you must provide info about the variable
args in the fixed arguments (a,b,c) or always include some end of list
value as the last argument.  But this means that you always have to
include this value even when you don't have any variable arguments.
(Also, there must be some value which is not valid over the union of
all possible variable arguments.)

I suppose the reason for this is efficiency.  The caller need only
push the extra args somewhere and not construct a real list.

Possible solutions require compiler support: 
 - Construct a real list such that the end of the list is nonambiguous
 - Pass a count of the args such that a va_arg will decrement it and a
   predicate (i.e. va_argp()) to test whether args are left.

This appears to have the same philosophical roots as passing arguments
by reference in C.  That is, in order to acheive X, both the caller
and callee must have have similar explicit notations.  I call this the "write
it in two places" syndrome.  This is also manifest in the header
file/source file redundancies (where you must maintain two files with
essentially the same (subset) information.  Flame and I'll explain.
(but this is a seperate issue).

-- 
Eric A. Raymond  (raymond@ptolemy.arc.nasa.gov)
"A hungry mob is an angry mob"

chris@mimsy.UUCP (Chris Torek) (04/11/89)

In article <1077@ptolemy.arc.nasa.gov> raymond@ptolemy.arc.nasa.gov
(Eric A. Raymond) writes:
>The variable argument facility as provided by STDARG.H (in the ANSI
>standard?) appears to have a severe limitation. ... there is no way
>to know when you have reached the end of [the optional argument] list.

We have had this flamefest before, and all that ever comes of it is
`that is how it has always been'.

>Possible solutions require compiler support: 
> - Construct a real list such that the end of the list is nonambiguous
> - Pass a count of the args such that a va_arg will decrement it and a
>   predicate (i.e. va_argp()) to test whether args are left.

The first solution is preferable for monotonic argument lists.  As for
the second, consider the following example:

	f(int fixedarg, ...) {
		va_list ap;
		va_start(ap);
		<code>
	}

	<more code>
		f(17, "here is a string", 95, 1.41421356);
		f(44, &some_integer, 3.14159265358979, 2);

Both invocations to f() have four arguments.  va_argp() or va_nargs()
or . . . will thus indicate four arguments for both calls.  That
means both calls are to be handled identically?  Nope.

The *number* of variable arguments is NOT sufficient information;
you need also the *types* of the arguments.

(If you want &rest, you know where to find it.  Many compiled lisps
are competitive with compiled C for speed, at least until you GC.)

>This appears to have the same philosophical roots as passing arguments
>by reference in C.  That is, in order to acheive X, both the caller
>and callee must have have similar explicit notations.  I call this the "write
>it in two places" syndrome.  This is also manifest in the header
>file/source file redundancies (where you must maintain two files with
>essentially the same (subset) information.  Flame and I'll explain.
>(but this is a seperate issue).

It is indeed.  Note, however, that natural languages also have
redundancies; a limited amount of redundancy improves clarity by
providing reassurance.  Mechanical anaysis (lint) can verify that the
duplicate information matches, while for the programmer, the notation
at either the call site or the callee provides information about the
number and types of arguments.  (Personally, I hate the `feature'
that Pascal subroutines can modify parameters by declaring them
`var' in a file I never see.  But then I think arrays should be
passed by value :-) .)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris