Syntax of function prototypes...
Chris Torek
chris at mimsy.UUCP
Sat Aug 20 11:57:08 AEST 1988
In article <4165 at adobe.COM> burgett at steel.COM (Michael Burgett) writes
[in re `int foo();' as a `prototype' declaration]:
>By function prototyping you have to declare the type and number (or
>indicate that there is a variable number) of parameters ....
Right: the key is that while `int foo();' *is* a function declaration,
it is *not* a /prototype/ declaration.
>If this [form of declaration] is used with ANSI I believe the
>compiler will look at the first time you use a function to determine the
>arguments...
Any compiler that does this implements none of the draft proposed
American National Standards for C. The declaration
int foo();
is morally equivalent to the prototype declaration
int foo(...);
although the latter is in fact illegal.
Aside: I think this illegality is a mistake, though a minor one.
Consider the `tovector' function, which counts the number of valid
pointers passed to it and constructs a vector holding this list, then
passes the vector as an argument to a function. It is called as
`tovector([optional PTR arguments], (PTR)NULL)'. Here it is in `old
C', slightly compressed vertically:
typedef char *PTR; /* generic pointer type */
#define NULL 0
#include <varargs.h>
char *malloc();
PTR *tovector(va_alist) va_dcl {
int veclen;
PTR *v, *p;
va_list ap;
/* find the vector length, including the NULL */
va_start(ap);
veclen = 0;
do veclen++; while (va_arg(ap, PTR) != NULL);
va_end(ap);
/* create the vector */
v = (PTR *)malloc((unsigned)veclen * sizeof(PTR));
if (v == NULL) return (NULL);
va_start(ap);
for (p = v; (*p++ = va_arg(ap, PTR)) != NULL;) /* void */;
va_end(ap);
return (v);
}
This is reasonably straightforward.
Here it is again, this time in dpANS C:
typedef void *PTR; /* generic pointer type */
#include <stddef.h>
#include <stdarg.h>
PTR *tovector(PTR firstarg, ...) {
int veclen;
PTR *v, *p;
va_list ap;
/* find the vector length, including the NULL */
veclen = 1;
if (firstarg != NULL) {
va_start(ap, firstarg);
do veclen++; while (va_arg(ap, PTR) != NULL);
va_end(ap);
}
/* create the vector */
v = (PTR *)malloc((unsigned)veclen * sizeof(PTR));
if (v == NULL) return (NULL);
p = v;
*p++ = firstarg;
if (firstarg != NULL) {
va_start(ap, firstarg);
while ((*p++ = va_arg(ap, PTR)) != NULL) /* void */;
va_end(ap);
}
return (v);
}
Notice that this time the code must be littered with special
tests for the first argument.
Certainly this is a rare case: most varargs appear after 1, 2, or
even more fixed arguments, and this problem does not arise. But
it is not a nonexistent case, and the inelegance of disallowing
no fixed arguments is at least inconvenient. (How is that for a
sentence full of negatives? :-) )
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list