[comp.lang.c] Type of function returning function.

rmf@media.uucp (Roger Fujii) (07/10/90)

So, just how does one type a function returning a pointer to a function?
(other than the obvious void *)

Example:

int foo(buff)
char	*buff;
{
	return atoi(buff);
}

TYPE bar()
{
	return foo;
}

I would have thought that it would be something like
int ((*)()), but gcc doesn't agree.  Help...

-- 
Roger Fujii - Media Cybernetics		Phone: (301)495-3305
Internet: rmf%media@uunet.uu.net 	UUCP: {uunet,hqda-ai}!media!rmf

diamond@tkou02.enet.dec.com (diamond@tkovoa) (07/11/90)

In article <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:
>So, just how does one type a function returning a pointer to a function?
>(other than the obvious void *)

The obvious (void *) does not work, except by accident on some machines
(and, depending on the machine, some segmentation models).  (void *) only
works for pointers to data.

For your example below,

typedef int (*TYPE)(char *);
>int foo(buff) char *buff; { return atoi(buff); }
>TYPE bar() { return foo; }

Alternatively,

int (*bar())(char *) { return foo; }

I recommend the typedef.
-- 
Norman Diamond, Nihon DEC     diamond@tkou02.enet.dec.com
This is me speaking.  If you want to hear the company speak, you need DECtalk.

mneerach@inf.ethz.ch (Matthias Ulrich Neeracher) (07/11/90)

In article <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:
>So, just how does one type a function returning a pointer to a function?
>(other than the obvious void *)
>Example:
>int foo(buff)
>char	*buff;
>{
>	return atoi(buff);
>}
>
>TYPE bar()
>{
>	return foo;
>}

I always program things like this using an intermediate typedef :

typedef int (*MyProcType)(); 

MyProcType bar() { return foo; } 

or more ANSI-like :

typedef int (*MyProcType)(char);

MyProcType bar() { return foo; }

I don't know how to declare functions like this directly; I don't care.
Why make you life unnecessarily hard ?

Matthias

will@kfw.COM (Will Crowder) (07/11/90)

In article <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:
>So, just how does one type a function returning a pointer to a function?
>(other than the obvious void *)
>
>Example:
>
>int foo(buff)
>char	*buff;
>{
>	return atoi(buff);
>}
>
>TYPE bar()
>{
>	return foo;
>}
>
>I would have thought that it would be something like
>int ((*)()), but gcc doesn't agree.  Help...
>
>-- 
>Roger Fujii - Media Cybernetics		Phone: (301)495-3305
>Internet: rmf%media@uunet.uu.net 	UUCP: {uunet,hqda-ai}!media!rmf

These are a pain.

int (*bar())();

ought to do it for you though.  I'm sure it's been discussed here before,
but there exists something called the "right-left" rule for deciphering
and creating C declarations, and it comes in quite handy.  If you haven't
heard of it, ask your local C guru or e-mail me, and I'll be happy to
explain it.

OBTW, if you want a full prototype, based on what you have above, it would
be:

int (*bar(void))(char *);

and the typedef would be:

typedef int (*TYPE(void))(char *);

or

typedef int (*TYPE())();

without the prototypes.

Hope this helps,

Will

dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) (07/11/90)

In article <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:
>So, just how does one type a function returning a pointer to a function?
>(other than the obvious void *)
>
>Example:
>
>int foo(buff)
>char	*buff;
>{
>	return atoi(buff);
>}
>
>TYPE bar()
>{
>	return foo;
>}
>

Those who suggested it would be clearer using a typedef are probably
right, but it's no big deal doing it directly either.

As always, declare things the same way they will be used.

In an expression, bar () will be a pointer to a function. To use this,
you would dereference the pointer ---  *bar () ---- and then use it for
a function call  --- (*bar ()) () --- which returns an int. 

int (*bar ()) ()
{
  return foo;
}

should work fine.

I've only used Classic C, but I believe the way it is done in ANSI
C is as follows:


int foo (char *buf)
{
  return atoi (buf);
}

int (*bar (void)) (char *)
{
  return foo;
}

where the type of bar is changed to function taking no arguments
returning a pointer to a function taking a char * and returning
an int.



--
Dave Eisen                      	    Home: (415) 323-9757
dkeisen@Gang-of-Four.Stanford.EDU           Office: (415) 967-5644
1447 N. Shoreline Blvd.
Mountain View, CA 94043

david@csource.oz.au (david nugent) (07/12/90)

In <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:

>So, just how does one type a function returning a pointer to a function?
>(other than the obvious void *)

>Example:

>int foo(buff)
>char	*buff;
>{
>	return atoi(buff);
>}

>TYPE bar()
>{
>	return foo;
>}

>I would have thought that it would be something like
>int ((*)()), but gcc doesn't agree.  Help...


Believe it or not (it looks quite strange):

int (*bar (void))()
{
	return foo;
}

-- 
_______________________________________________________________________________
 Unique Computing Pty Ltd  Melbourne  Australia  -  Communications Specialists 
        david@csource.oz.au    3:632/348@fidonet    28:4100/1@signet           

ckp@grebyn.com (Checkpoint Technologies) (07/13/90)

In article <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:
>So, just how does one type a function returning a pointer to a function?
                                                                ^^^^^^^^
To start with, function-ness is not a "terminating" data type.  What you
really mean to say is I want a TYPE representing a pointer to a function
returning an *int* (as in your example).

>Example:
>
>int foo(buff)
>char	*buff;
>{
>	return atoi(buff);
>}
>
>TYPE bar()
>{
>	return foo;
>}

You could think about it this way:

typedef int (*TYPE)(); /* TYPE is a pointer to a function returning int */

or, with prototypes for the above example:

typedef int (*TYPE)(char *buff);

This typedef would make the above example work (I think).  Without the
typedef, bar() would be defined as:

int (*)() bar()  /* well, this DOES look weird... */
{
...
}
er, or maybe...
int (*) (bar()) ()  /* nah, I think the first one is right... */
{
...
}

>I would have thought that it would be something like
>int ((*)()), but gcc doesn't agree.  Help...

Well, try the second one above.

>Roger Fujii - Media Cybernetics		Phone: (301)495-3305
>Internet: rmf%media@uunet.uu.net 	UUCP: {uunet,hqda-ai}!media!rmf

Chris

-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                                    \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/

johnb@srchtec.UUCP (John Baldwin) (07/13/90)

In article <1990Jul11.165805.14866@Neon.Stanford.EDU>,
 dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) writes:
>
>int (*bar ()) ()
>{
>  return foo;
>}
>
>should work fine.
>

Not to the best of my knowledge.  "Bar" is already defined as a function
and here it is being defined again.  Or did you mean something different?
-- 
____________________________________________________________________________
John T. Baldwin			| The opinions expressed are not my own, nor
search technology, inc.		| do they belong to my employer.
johnb@srchtec.uucp		| They came from outer space.

williams@umaxc.weeg.uiowa.edu (Kent Williams) (07/13/90)

In article <20299@grebyn.com> ckp@grebyn.UUCP (Checkpoint Technologies) writes:
>In article <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:
>>So, just how does one type a function returning a pointer to a function?
>                                                                ^^^^^^^^
This brings up an interesting conundrum:

Suppose, for example, you want to implement a state machine as a set of
functions.   The strategy is for each function to return a pointer to the
next function to be called, and let NULL indicate final state.  So you have

typedef SOMETYPE fp;
fp state2(), state3();

fp state1() { return state2; }
fp state2() { return state3; }
fp state3() { return (fp)NULL; }

void statemachine() {
		fp current;
		current = state1;
		while((current = (current)()) != NULL)
				;
}

Simple enough, C-like enough, but you cannot specify SOMETYPE -- you
get involved in an infinite regress!

The problem is that you want to define SOMETYPE as

typedef FUNCTION_RETURNING_POINTER_TO_SOMETYPE SOMETYPE;

which is recursive -- so you have to do something like

typedef void (*fp)();

and then use casts everywhere to make things come out right.  The
problem is that you can't do to function pointers what you can with
structs -- make them self-referential.  This is done in C by fiat --
you can refer to a pointer to a structure before the structure is
fully specified, and refer to unspecified structure types generally --
e.g. You can do something like

struct never_defined_anywhere;

struct never_defined_anywhere *function_returning_pointer_to();

So long as you don't try to get any fields of never_defined_anywhere;


--
Kent Williams                    'Look, I can understand "teenage mutant ninja 
williams@umaxc.weeg.uiowa.edu    turtles", but I can't understand "mutually 
williams@herky.cs.uiowa.edu      recursive inline functions".' - Paul Chisholm

volpe@underdog.crd.ge.com (Christopher R Volpe) (07/17/90)

In article <1852@ns-mx.uiowa.edu>, williams@umaxc.weeg.uiowa.edu (Kent
Williams) writes:
> 
> typedef SOMETYPE fp;
> fp state2(), state3();
> 
> fp state1() { return state2; }
> fp state2() { return state3; }
> fp state3() { return (fp)NULL; }
> 
> void statemachine() {
> 		fp current;
                   ^^^^^^^
> 		current = state1;
> 		while((current = (current)()) != NULL)
> 				;
> }
> 

Minor point, but "current" doesn't hold an fp, it holds the address
of a function returning an fp, right? 

                fp (*current)();


Also, you can take advantage of the self referential abilities of
structs to do what you want with functions without any typecasts,
although it is debatable whether or not the following is any
less kludgy (it does compile under gcc, though):

typedef struct somestruct {
    struct somestruct (*field)();
    } fp;

fp f1(),f2();

fp f1()
{
  fp dummy;
  dummy.field=f2;
  return dummy;
}

fp f2()
{
  fp dummy;
  dummy.field=f1;
  return dummy;
}

void statemachine() {
                fp (*current)();
                current = f1;
                while((current = (current)().field) != NULL)
                                ;
}

Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

hannum@schubert.psu.edu (Charles Hannum) (07/19/90)

In article <20299@grebyn.com> ckp@grebyn.com (Checkpoint Technologies) writes:

   In article <1990Jul10.024205.17382@media.uucp> rmf@media.uucp (Roger Fujii) writes:
   >So, just how does one type a function returning a pointer to a function?
								   ^^^^^^^^
   To start with, function-ness is not a "terminating" data type.  What you
   really mean to say is I want a TYPE representing a pointer to a function
   returning an *int* (as in your example).


schubert> cdecl
Type `help' or `?' for help
cdecl> declare foo as function returning pointer to function returning int
int (*foo())()
cdecl>

Once again...  cdecl is your friend!
--
 
Virtually,
Charles Martin Hannum		 "Those who say a thing cannot be done should
Please send mail to:		  under no circumstances stand in the way of
hannum@schubert.psu.edu		  he who is doing it." - a misquote