[comp.lang.c] Syntax of function prototypes...

U23405@UICVM (08/14/88)

Does anyone know (or know where to find) information about the syntax of
function prototypes? For example, is this correct:?

          int something(int a; float b; char c;);
          ...
          int something(int a; float b; char c;)
          {
               a += (int) b - (int) c;
               return a;
          }
          ...
          something(1,2.0,'x');

For example, do the variable names in the function declaration have to agree
with the variable names in the function definition, etc.?

                                                 Michael Steiner
                                                 Email: U23405@UICVM

lmiller@venera.isi.edu (Larry Miller) (08/18/88)

In article <8808171403.AA05181@ucbvax.Berkeley.EDU> U23405@UICVM writes:
>Does anyone know (or know where to find) information about the syntax of
>function prototypes? For example, is this correct:?
>
>          int something(int a; float b; char c;);
>          ...
>          int something(int a; float b; char c;)
>          {
>               a += (int) b - (int) c;
>               return a;
>          }
>          ...
>          something(1,2.0,'x');
>
>For example, do the variable names in the function declaration have to agree
>with the variable names in the function definition, etc.?
>

The variable names do not need to agree; in fact, they are not necessary in
the function DECLARATION (prototype).  If names are used, they have scope
only to the end of the declaration.  Any of the following will do,
given the function definition above (except you must use commas, not
semicolons):

definition          int something(int a, float b, char c)

possible prototypes
	  int something(int a, float b, char c);
          int something(int n, float x, char c1);
          int something(int, float, char);

Larry Miller				lmiller@venera.isi.edu (no uucp)
USC/ISI					213-822-1511
4676 Admiralty Way
Marina del Rey, CA. 90292

bph@buengc.BU.EDU (Blair P. Houghton) (08/19/88)

In article <6105@venera.isi.edu> lmiller@venera.isi.edu.UUCP (Larry Miller) writes:
>In article <8808171403.AA05181@ucbvax.Berkeley.EDU> U23405@UICVM writes:
>>Does anyone know (or know where to find) information about the syntax of
>>function prototypes? For example, is this correct:?
[...]
>>For example, do the variable names in the function declaration have to agree
>>with the variable names in the function definition, etc.?
>
>The variable names do not need to agree; in fact, they are not necessary in
>the function DECLARATION (prototype).  If names are used, they have scope
>only to the end of the declaration.  Any of the following will do,
[...]
>
>definition          int something(int a, float b, char c)
>
>possible prototypes
>	  int something(int a, float b, char c);
>          int something(int n, float x, char c1);
>          int something(int, float, char);

Am I missing something (there _is_ an echo in here; I should have
"am I missing something" mapped to the spacebar...:-) or is

int something();

just as good (for a prototype) (except for the obviously better style
of the above, since they are virtually self-commenting)?

				--Blair

burgett@steel.COM (Michael Burgett) (08/19/88)

In article <871@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes:
>>
>>definition          int something(int a, float b, char c)
>>
>>possible prototypes
>>	  int something(int a, float b, char c);
>>          int something(int n, float x, char c1);
>>          int something(int, float, char);
>
>Am I missing something (there _is_ an echo in here; I should have
>"am I missing something" mapped to the spacebar...:-) or is
>
>int something();
>
>just as good (for a prototype) (except for the obviously better style
>of the above, since they are virtually self-commenting)?
>
yes you're missing something.  By function prototyping you have to declare the
type and number (or indicate that there is a variable number) of parameters
so that the compiler can play lint and check all usage of the function calls
throughout your code.  What you list indicates that "something" is a function
returning an int, but nothing else.  If this is used with ANSI I believe the 
compiler will look at the first time you use a function to determine the 
arguments...

		mike burgett

				burgett!adobe@decwrl.dec.com

karl@haddock.ima.isc.com (Karl Heuer) (08/19/88)

In article <871@buengc.BU.EDU> bph@buengc.BU.EDU (Blair P. Houghton) writes:
>Am I missing something or is "int something();" just as good (for a
>prototype) (except for [style])?

You are missing something.  "int something();" is not a prototype; that word
is reserved for the new syntax.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

karl@haddock.ima.isc.com (Karl Heuer) (08/20/88)

In article <4165@adobe.COM> burgett@steel.COM (Michael Burgett) writes:
>[int something();] indicates that "something" is a function returning an int,
>but nothing else.  If this is used with ANSI I believe the compiler will look
>at the first time you use a function to determine the arguments...

No, the correct behavior in the absence of a prototype is to simply apply the
default argument promotion rules and call the function.  The behavior is
undefined if the actual (promoted) arguments are not compatible with the
formal parameters, though, so if you have "something(1)" and "something(2.0)"
then at least one of them would evoke undefined behavior if called.  This may
be grounds for a warning, but it doesn't allow the compiler to construct and
enforce a prototype.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

chris@mimsy.UUCP (Chris Torek) (08/20/88)

In article <4165@adobe.COM> burgett@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@mimsy.umd.edu	Path:	uunet!mimsy!chris

chris@mimsy.UUCP (Chris Torek) (08/20/88)

In article <13114@mimsy.UUCP> I wrote
>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.

Oops.  Make that `pointers passed to it, and returns a vector holding this
list.'
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

scjones@sdrc.UUCP (Larry Jones) (08/21/88)

In article <13114@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
> [ not allowing "int foo(...);" is a mistake ]

The reason that form is disallowed is because the <stdarg.h> macros require
the last argument before the ellipsis as an argument.  The reason the macros
require it is because some implimentors insisted they could not do varargs
without it.

----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@sdrc
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150                  AT&T: (513) 576-2070
Nancy Reagan on superconductivity: "Just say mho."