Path: utzoo!utgpu!attcan!uunet!seismo!sundc!pitstop!sun!decwrl!labrea!rutgers!ukma!uflorida!haven!mimsy!chris
From: chris@mimsy.UUCP (Chris Torek)
Newsgroups: comp.lang.c
Subject: Re: typedefs and prototypes
Message-ID: <13664@mimsy.UUCP>
Date: 21 Sep 88 14:08:12 GMT
References: <7135@bloom-beacon.MIT.EDU> <8543@smoke.ARPA>
Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742
Lines: 58

>In article <7135@bloom-beacon.MIT.EDU> tada@athena.mit.edu
>(Michael Zehr) asks:
>>typedef void (*Keyboard_widget)(int key, void *data);
>>void kb_widget1(int c, void *data)
>>I get a "conflicts with previous declaration" at that point.  If I try
>>to define the widget by the typedef, what syntax do i use???

In article <8543@smoke.ARPA> gwyn@smoke.ARPA (Doug Gwyn) answers:
>Use exactly the syntax of the typedef, minus "typedef", with the
>type name replaced by the identifier.

Right, but:

>I.e.
>	void (*kb_widget1)(int key, void *data) { ... }
>
>>Keyboard_widget kb_widget1  /* where do the formal parameters go??? */
>>{...}
>
>This one is a mystery to me too.

The formal parameters go nowhere: you have declared a type (with
the typedef) or an object (without the typedef) which translates
to `pointer to function(int, void *) returning void'.  Since it is
a pointer, it cannot be a function.

The syntax for `function returning pointer to function(int, void *)
returning void' is, of course,

	void (*here_is_fn(type1 arg1, etc))(int, void *) { ... }

and the formal parameters go where` type1 arg1, etc' sits.  Using
a typedef for `pointer to function(int, void *) returning void',
it simplifies to:

	/* pointer to function arg int arg pointer to void return void */
	/* ^          ^        ^   ^   ^   ^          ^    ^      ^ */
	typedef (*pfAiApvRv)(int, void *);

	pfAiApvRv here_is_fn(type1, arg1, etc) { ... }

Note that you cannot use a typedef to define a function type: i.e.,
`typedef func_arg_int_ret_int int(int);' is illegal.  The problem is
that, given this definition, there is nowhere to put the parentheses
and the formal, so that transforming

	/* identity fn */
	int identity(int i) { return i; }

to

	func_arg_int_ret_int identity { return i??? }

leaves us nowhere to declare `i'.  (If we needed no arguments, it
might work, but it makes the grammar inordinately difficult.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris