[net.lang.c] varargs.h

ark@alice.UUCP (Andrew Koenig) (02/22/85)

As the author of varargs, I would like to set the record straight.

The intention of varargs was that the type given to va_arg
should only be a type that is meaningful as a parameter.  Thus
char, short, and float are never meaningful because they
are automatically widened to int, int, and double respectively.

jim@ISM780B.UUCP (02/25/85)

>/* Written  4:19 am  Feb 23, 1985 by ark@alice in ISM780B:net.lang.c */
>As the author of varargs, I would like to set the record straight.
>
>The intention of varargs was that the type given to va_arg
>should only be a type that is meaningful as a parameter.  Thus
>char, short, and float are never meaningful because they
>are automatically widened to int, int, and double respectively.
>/* End of text from ISM780B:net.lang.c */

There is nothing in the language that says that parameters cannot be
declared as char, short, or float.  And if typeof is (should be!)
added to the language, this will become all the more important.
Since sizeof is a compile-time constant, there is no reason why
va_arg cannot widen appropriately via ?: .  Of course, you will want an
ifdef lint version to avoid all the "constant used in a conditional context"
messages.  And speaking of lint, someone should fix it so it does not do
type checking against VARARGS parameters (or maybe we need a /*VARTYPE*/
comment?)

-- Jim Balter, INTERACTIVE Systems (ima!jim)

ark@alice.UUCP (Andrew Koenig) (02/26/85)

>>As the author of varargs, I would like to set the record straight.
>>
>>The intention of varargs was that the type given to va_arg
>>should only be a type that is meaningful as a parameter.  Thus
>>char, short, and float are never meaningful because they
>>are automatically widened to int, int, and double respectively.

>There is nothing in the language that says that parameters cannot be
>declared as char, short, or float.  And if typeof is (should be!)
>added to the language, this will become all the more important.
>Since sizeof is a compile-time constant, there is no reason why
>va_arg cannot widen appropriately via ?: .  Of course, you will want an
>ifdef lint version to avoid all the "constant used in a conditional context"
>messages.  And speaking of lint, someone should fix it so it does not do
>type checking against VARARGS parameters (or maybe we need a /*VARTYPE*/
>comment?)

>-- Jim Balter, INTERACTIVE Systems (ima!jim)

Ummm -- my mistake.  I meant argument, not parameter.  Char and short
arguments are automatically cast to ints.  Float arguments are automatically
cast to doubles.  Thus there is no reason to use anything as the
second argument to va_arg except the wide types.

Yes, varargs could be changed to recognize the lengths of the narrow
types -- on some machines.  However, consider a machine where int
and float have the same size.

Anyway, even if you did manage to change varargs, all that would do
is encourage people to write "portable" programs that would only
run on the new version.  Best leave it as it is.

			--Andrew Koenig

geoff@ISM780.UUCP (02/28/85)

>>>char, short, and float are never meaningful because they
>>>are automatically widened to int, int, and double respectively.

>>Since sizeof is a compile-time constant, there is no reason why
>>va_arg cannot widen appropriately via ?: .  ...

>Yes, varargs could be changed to recognize the lengths of the narrow
>types -- on some machines.  However, consider a machine where int
>and float have the same size.

Well? So? and then?  Wouldn't the compiler know that, and act accordingly?
So the code is *marginally* slower, is this too big a price to pay for
correctness?  Or am I missing something?

>Anyway, even if you did manage to change varargs, all that would do
>is encourage people to write "portable" programs that would only
>run on the new version.  Best leave it as it is.
 ?????????????????????????^^???????????????????????????????????????(?)
Seems to me that a bug is a bug, are you saying it shouldn't be fixed because
it's already out?  A documented bug is *NOT* a feature!  Heaven forfend
someone should encourage people to write portable code!

	      Geoffrey Kimbrough -- INTERACTIVE Systems Corp.

      [ Whenever I see Oysters on a menu, I am reminded of a quote...]

jim@ISM780B.UUCP (03/01/85)

>Ummm -- my mistake.  I meant argument, not parameter.  Char and short
>arguments are automatically cast to ints.  Float arguments are automatically
>cast to doubles.  Thus there is no reason to use anything as the
>second argument to va_arg except the wide types.

I think you missed my point.  Consider the following:

/* In a header file far far away */
typedef short   foo_t;

/* Meanwhile, elsewhere ... */
caller() {
	foo_t   foovar;

	varfunc(foovar);
}

/*VARARGS*/
varfunc(va_alist) va_dcl
{
	va_list ap;
	foo_t   fooparm;
	int     intparm;

	va_start(ap);
	fooparm = va_arg(ap, foo_t);  /* ap only increased by sizeof(short) */
	intparm = vararg(ap, int);    /* WHOOPS! */
	...
	va_end(ap);
}

>Yes, varargs could be changed to recognize the lengths of the narrow
>types -- on some machines.  However, consider a machine where int
>and float have the same size.

Hmmm, this is a serious problem.  The only solution I can imagine is a
new compile-time feature that would allow you to determine whether two
types are the same, or a sizeofparameter keyword.  Sigh.

>Anyway, even if you did manage to change varargs, all that would do
>is encourage people to write "portable" programs that would only
>run on the new version.  Best leave it as it is.

If it were possible to implement it portably, I would disagree on the grounds
that people should be able to code to the spec, and not worry that some
implementation somewhere has a bug.  However, the inability to
know whether a 4-byte item is a float to be widened or simply an int
makes the issue moot.  Double sigh.

It would appear that the only thing available at this point is a major
caveat that only the widened types can be used.
In the example above, the best solution would probably be to add a

typedef int foo_parmt;  /* widened type of foo_t when passed as a parameter */

and use foo_parmt in varfunc().

-- Jim Balter, INTERACTIVE Systems (ima!jim)