[net.lang.c] declaring routines which return function pointers

lake@alberta.UUCP (Robert Lake) (12/11/84)

I have a routine which resembles the following:

	int (*f)();
	int fa(), fb();

	fa() {
		f = fb;
		return(f);
	}

	fb() {
	}

The problem with the above is that lint complains about an illegal combin-
ation of a pointer with an integer in the 'return' statement.  I have tried
various casts and function declarations to try to satisfy lint, but none of
them have worked.  Does anybody know what I should do to keep lint happy?

					Robert Lake (alberta!lake)
					University of Alberta

robert@gitpyr.UUCP (Robert Viduya) (12/14/84)

> I have a routine which resembles the following:
> 
> 	int (*f)();
> 	int fa(), fb();
> 
> 	fa() {
> 		f = fb;
> 		return(f);
> 	}
> 
> 	fb() {
> 	}
> 
> The problem with the above is that lint complains about an illegal combin-
> ation of a pointer with an integer in the 'return' statement.  I have tried
> various casts and function declarations to try to satisfy lint, but none of
> them have worked.  Does anybody know what I should do to keep lint happy?
> 

I played around with the code for about 30 minutes and the only thing I
accomplished was to make lint core dump twice.  I only see one way of
doing it and C apparently doesn't support it.  That way is to declare
fa() as:

    int ((*fa)())();

This is broken down from:

    int  (*x)();	/* x is a pointer to a function returning an int */
    int ((*y)())();	/* y is function returning a ptr to a func returning an int */

However, both lint and cc complain with 'function returns illegal type'.

May I suggest using casts?

				robert
-- 
Robert Viduya
Office of Computing Services
Georgia Institute of Technology, Atlanta GA 30332
Phone:  (404) 894-4669

...!{akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp}!gatech!gitpyr!robert
...!{rlgvax,sb1,uf-cgrl,unmvax,ut-sally}!gatech!gitpyr!robert

egs@epsilon.UUCP (Ed Sheppard) (12/17/84)

Yeah, I ran into this once before. Instead of

    int ((*fa)())();

as Robert suggests, try using this

    typedef	int	(*FP)();

    int	f() {}

    FP	fa() { return(f); }

which seems to get by our 4.2 cc. Seems kind of ridiculous to me.

						Ed Sheppard
						Bell Communications Research

plw@mgweed.UUCP (Pete Wilson) (12/17/84)

	In the following truly useless code, lint(1) on Sys V only
complains about 'x' being set but not used. The code was derived from
reading the man section on signal(2):

	main()
	{
		int fa();
		int (*fr())();
		int (*x)();
	
		x = fr(fa);
	
	}
	int (*fr(fp))()
	int (*fp)();
	{
		int nfp();
	
		if ( fp )
			return(fp);
		return(nfp);
	}
	nfp()
	{
		return(0);
	}
	fa()
	{
		return(0);
	}

	Unfortunately, K&R is not too clear about functions which return
pointers to functions. Consistance in declarations and definitions is
what keeps lint happy. Notice the declaration of 'fr' in 'main'. It is
declared as a function which returns a pointer to a function. Later in
the file it is defined in the same way.
	Derivation:

	int f();	/* function which returns an int */
	int *f();	/* function which returns a pointer to an int */
	int (*f)();	/* holds a pointer to a function */
	int (*f())();	/* function which returns a pointer to a
			   function which returns an int */
	???		/* holds a pointer to a function which returns
			   a pointer to a function which returns an
			   int???   DON'T ASK!! */
	
	Still not very clear? I agree!! One can get lost in the depths
of parentheses!!

					Pete Wilson
					AT&T-CP Montgomery Works
					Montgomery, IL
					..ihnp4!mgweed!plw

chris@umcp-cs.UUCP (Chris Torek) (12/17/84)

> > I have a routine which resembles the following:
> > 
> > 	int (*f)();
> > 	int fa(), fb();
> > 
> > 	fa() {
> > 		f = fb;
> > 		return(f);
> > 	}
> > 
> > 	fb() {
> > 	}
> > 
> > The problem with the above is that lint complains about an illegal combin-
> > ation of a pointer with an integer in the 'return' statement.  I have tried
> > various casts and function declarations to try to satisfy lint, but none of
> > them have worked.  Does anybody know what I should do to keep lint happy?
> > 

> I played around with the code for about 30 minutes and the only thing I
> accomplished was to make lint core dump twice.

Oh good grief!  Try

	int (*f)();
	int fb();
	int (*fa())();

	int (*fa())() {
		f = fb;
		return f;
	}

	fb() {
	}
-- 
(This line accidently left nonblank.)

In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

ron@brl-tgr.ARPA (Ron Natalie <ron>) (12/17/84)

> I have a routine which resembles the following:
> 
> 	int (*f)();
> 	int fa(), fb();
> 
> 	fa() {
> 		f = fb;
> 		return(f);
> 	}
> 
> 	fb() {
> 	}
> 
> The problem with the above is that lint complains about an illegal combin-
> ation of a pointer with an integer in the 'return' statement.  I have tried
> various casts and function declarations to try to satisfy lint, but none of
> them have worked.  Does anybody know what I should do to keep lint happy?
> 
> 					Robert Lake (alberta!lake)
> 					University of Alberta

Have you tried declaring fa as a function returning pointer to function?

keesan@bbncca.ARPA (Morris Keesan) (12/18/84)

----------------
USE TYPEDEFS!!

Sure, you can use "longhand", and declare f as a pointer to function returning
int, and declare fa as a function returning a pointer to function returning
int, but even if you know what you're doing [ basic rule -- as you pronounce
the English from left to right, build the declaration from the innermost
parentheses out ] and manage to correctly build the declarations

    int (*f)();
    int (*(fa()))();    /* Yes, I know there's a redundant pair of () */

you've got code which the next person will have to spend five minutes
deciphering, even with comments.  Compare the above with

    typedef (*PFI)();   /* Pointer to function returning int */
    PFI f, fa();

Why would anyone choose the former?  This, to my mind, is the major beauty of
typedefs.  Information hiding is all well and good, but can be accomplished by
judicious use of #defines, without typedefs.  Using typedefs allows you to
break down complex type declarations into manageable chunks, providing much
more readable code, and much less chance of getting the declaration wrong in
the first place.
-- 
			    Morris M. Keesan
			    {decvax,linus,ihnp4,wivax,wjh12,ima}!bbncca!keesan
			    keesan @ BBN-UNIX.ARPA

howard@cyb-eng.UUCP (Howard Johnson) (12/18/84)

> I have a routine which resembles the following:
> 
> 	int (*f)();
> 	int fa(), fb();
> 
> 	fa() {
> 		f = fb;
> 		return(f);
> 	}
> 
> 	fb() {
> 	}
> 
> The problem with the above is that lint complains about an illegal combin-
> ation of a pointer with an integer in the 'return' statement.  I have tried
> various casts and function declarations to try to satisfy lint, but none of
> them have worked.  Does anybody know what I should do to keep lint happy?

I thought more people knew the answer to this one.  On our Unisoft System V
system, the signal system call looks something like this:

	int (*signal(sig, func))()
	int (*func)();
	{
		static int (*oldsig)();

		/* code */;
		return(oldsig);
	}
-- 
	Howard Johnson		Cyb Systems, Austin, TX
..!{gatech,harvard,ihnp4,nbires,noao,seismo}!ut-sally!cyb-eng!howard

chris@umcp-cs.UUCP (Chris Torek) (12/19/84)

Maybe someone should re-post the ``cdecl'' program:

  % cdecl
  declare f as pointer to function returning pointer to function returning int
  int (*(*f)())()
  declare x as pointer to pointer to function returning pointer to function returning pointer to pointer to pointer to function returning pointer to function returning pointer to char
  char *(*(***(*(**x)())())())()
  %

It even works the opposite direction:

  % cdecl
  explain char (**(*f())())()
  declare f as function returning pointer to function returning pointer to pointer to function returning char
  %
-- 
(This line accidently left nonblank.)

In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

ken@rochester.UUCP (Ken Yap) (12/20/84)

In article <1998@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes:
>Maybe someone should re-post the ``cdecl'' program:
>
>  % cdecl
>  declare f as pointer to function returning pointer to function returning int
>  int (*(*f)())()
>  declare x as pointer to pointer to function returning pointer to function returning pointer to pointer to pointer to function returning pointer to function returning pointer to char
>  char *(*(***(*(**x)())())())()
>...

Ah, but what I want is the DWIM (declare what I mean) program :-).
-- 
	Ken Yap

UUCP: (..!{allegra, decvax, seismo}!rochester!ken) ARPA: ken@rochester.arpa
USnail:	Dept. of Comp. Sci., U. of Rochester, NY 14627.

lmc@denelcor.UUCP (Lyle McElhaney) (12/20/84)

> Maybe someone should re-post the ``cdecl'' program:

Yes, please. I have been waiting for it for some time.
-- 
Lyle McElhaney
{hao, stcvax, brl-bmd, nbires, csu-cs} !denelcor!lmc