varargs.h
jim at ISM780B.UUCP
jim at ISM780B.UUCP
Fri Mar 1 15:44:25 AEST 1985
>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)
More information about the Comp.lang.c
mailing list