[net.lang.c] Function returning pointer to function ?

RIZZI@USC-ISIB.ARPA (Bill Rizzi) (07/15/85)

[]

	Is it legal for a function to return a pointer to a function?
It seems like it should be, but if so, how would one define and
declare such a function?

	Replies to me please, unless you feel the net needs a diversion
from the debating on matters of style and efficiency.

	Bill (RIZZI@ISIB)		That's all folks!!


-------

john@frog.UUCP (John Woods) (07/17/85)

> 	Is it legal for a function to return a pointer to a function?
> It seems like it should be, but if so, how would one define and
> declare such a function?
> 

typedef int (*pfi)();

int spiffy() {
	return 0x69;
}

pfi foobar() {
	return spiffy;
}

There you have it.  It's simple, and EVEN readable.  Nearly so, anyway.


--
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw%mit-ccc@MIT-XX.ARPA

I have a bad habit of thinking of tremendously witty .signatures just before
I fall asleep.  If I kept paper by my bed, you'd probably be laughing
uncontrollably at this very moment.  Sorry.

pete@kvvax4.UUCP (Peter J Story) (07/18/85)

> Replies to me please, unless you feel the net needs a diversion
> from the debating on matters of style and efficiency.

It certainly does!  In any case that ARPA gap always defeats my mail.

> Is it legal for a function to return a pointer to a function?

Yes, here is some playing that I did, together with a similar problem
which I have never solved.  Maybe someone can help.

/* I had better apologise for the cryptic naming, but in the     */
/* interest of compactness...  The basic rule for declarations   */
/* is to try to figure out how you would access the basic object */
/* from an object of the type you are trying to declare, and     */
/* make the declaration look like that.  It often helps to build */
/* it up from smaller units, thus:                               */

int a = 6;
int fi() {return(a);}		    /* fn returning an int */
int *fpi() {return(&a);}	    /* fn returning ptr to int */
int (*pfi)() = fi;		    /* ptr to fn returning int */

/* Now the tricky bit.  Imagine I had a function which returned  */
/* a pointer to a function returning an int.  Then I could       */
/* assign its result to pfi, thus: pfi = gfpfi();                */
/* Put this in the declaration of pfi above, and you are there   */

int (*gfpfi())() {return(pfi);};    /* fn returning ptr to fn returning int */

/* a step further? */

int *(*pfpi)() = fpi;		    /* ptr to fn returning ptr to int */
int *(*gfpfpi())() {return(pfpi);}; /* fn rtning ptr to fn rtning ptr to int */

main()
{
   int x;
   x = (*pfi)();	printf("%d",x);
   x = *(*pfpi)();	printf("%d",x);
   x = (*gfpfi())();	printf("%d",x);
   x = *(*gfpfpi())();	printf("%d",x);
   printf("\n");
   myproblem();  /* see below !! */
}

/* ---------------------------------------------------------- */

/* Now my turn to ask a question.  Here are the declarations: */
 
char *f1()  { return("1"); }
char *f2()  { return("2"); }

/* decl array of ptrs to fns returning ptr to char */
char *(*funcs[2])() = {f1,f2};

/* decl ptr to array of ptrs to fns returning ptr to char */
char *(*(*pfuncs)[])() = funcs; 

/* "junk.c", line 47: warning: illegal pointer combination        */
/* I can't get that to compile without a warning but it works ok. */

/* It should be analogous to this, which also won't compile      */
/* without a warning.						 */
char cd[2] = {'c','d'};
char (*pcd)[] = cd;
/* "junk.c", line 55: warning: illegal pointer combination        */

/* What is it that the compiler (4.1 BSD) doesn't like?          */

myproblem()
{
   int i;
   for (i=0; i<2; i++) printf("%c",*(*funcs[i])());	/* 12 */
   for (i=0; i<2; i++) printf("%c",*(*(*pfuncs)[i])());	/* 12 */
   printf("%c",(*pcd)[0]);				/* c */
   printf("\n");
}
-- 
Pete Story	      {decvax,philabs}!mcvax!kvport!kvvax4!pete
A/S Kongsberg Vaapenfabrikk, PO Box 25, N3601 Kongsberg, Norway
Tel:  + 47 3 739644   Tlx:  71491 vaapn n

chris@umcp-cs.UUCP (Chris Torek) (07/20/85)

Once again, ``cdecl'' to the rescue:

> /* Now my turn to ask a question.  Here are the declarations: */
> char *f1()  { return("1"); }
> char *f2()  { return("2"); }
> /* decl array of ptrs to fns returning ptr to char */
> char *(*funcs[2])() = {f1,f2};
> /* decl ptr to array of ptrs to fns returning ptr to char */
> char *(*(*pfuncs)[])() = funcs; 
> /* "junk.c", line 47: warning: illegal pointer combination        */
> /* I can't get that to compile without a warning but it works ok. */

% cdecl << eof
declare pfuncs as pointer to array of pointer to function returning pointer to char
eof
Warning: Unsupported in C -- Pointer to array of unspecified dimension
char *(*(*pfuncs)[])()
%

It not only gives you the required declaration, it even tells you why
the compiler won't like it!  :-)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland