[net.lang.c] pointers to functions

dave@andromeda.UUCP (Dave Bloom) (01/09/86)

<>
Here's a good(?) question. Lets say I have this:

main()
{
	int a(), b();  /* defined somewhere else */
	int (*c)();    /* a pointer to a function returning int (K&R pg141) */
		.
		.
		.
	c = b;
	(*c)(some arguments);
}

Our compiler claims c is an "illegal function", yet the following it
permits:

main()
{
	int a(), b();

	a(b);
}
a(x)
int (*x)();
{
	(*x)(some arguments);
}

Looks like I'm missing something. Can anyone out the lend me a hand???
What is it that's wrong in example one? How can I declare a generic pointer
to an int-function, set it equal to the address of a valid int function,
and use it instead of the function????

Thanx.
-- 

-------------------------------------------------------------------------------
      allegra\					       Dave Bloom
      harvard \ pyramid\
       seismo  \  pyrnj >!andromeda!dave         HOME: (201) 868-1764
     ut-sally   >!topaz/			 WORK: (201) 648-5083
       sri-iu  /
ihnp4!packard /		           "You're never alone with a schizophrenic...."

davidsen@steinmetz.UUCP (01/13/86)

As far as I can see, your example as posted was correct. I tried it on a
4.2BSD and SysIII systems, and both thought it was fine. Microsoft C loved it!
It's valid by both K&R and X3J11 (proposed). Either your compiler is being
silly, or perhaps you have a glitch in the source code. Assuming that you
can't compile the fragment as posted, I would complain.

---------------- < disclamer > ----------------
I don't usually bother, but this is a special case. The opinion expressed is
my personal opinion, and is not an official statement of my alter-ego, the
former GE representative to X3J11. It may not be the official position of my
company and/or its affiliates.
-- 
	-bill davidsen

	seismo!rochester!steinmetz!--\
       /                               \
ihnp4!              unirot ------------->---> crdos1!davidsen
       \                               /
        chinet! ---------------------/        (davidsen@ge-crd.ARPA)

"It seemed like a good idea at the time..."

martinl@molihp.UUCP (Martin M Lacey) (01/15/86)

In article <59@andromeda.UUCP> dave@andromeda.UUCP (Dave Bloom) writes:
><>
>Here's a good(?) question. Lets say I have this:
>
>main()
>{
>	int a(), b();  /* defined somewhere else */
>	int (*c)();    /* a pointer to a function returning int (K&R pg141) */
>		.
>		.
>		.
>	c = b;
>	(*c)(some arguments);
>}
>
>Our compiler claims c is an "illegal function", 
> [...]
>Looks like I'm missing something. Can anyone out the lend me a hand???
>What is it that's wrong in example one? How can I declare a generic pointer
>to an int-function, set it equal to the address of a valid int function,
>and use it instead of the function????
>
>Thanx.
>-- 
>     			       Dave Bloom


I have just tested the above on our system (Sys 5 rel 2: HP9000 series 500)
and it works no problem.  Your compiler is out-dated probably.

		Magic Martin.

toma@killer.UUCP (Tom Armistead) (06/20/86)

The delima - Is it possible to cast a 'pointer to' a function?

What I have is a char * that holds the address of a function.
int	foo();
char	*addr = foo;
Would it be possible to call the function foo() via the variable addr?

Secondly is it possible to have an array of type 'pointer to' function.
i.e. 
int  (*function)()[SIZE];
something like the above, I was able to achieve this using this:
struct	fct {
            int  (*func)();
            } f_array[SIZE];
function()
{
    int x;
    printf("offset: ");
    scanf("%d",&x);
    (*f_array[x].func)();
}
Is there another way???

Something to think about...
Thanx in advance for **ANY** help,
- Tom

---
UUCP:
     ihnp4!cuae2!tuxa!we53!sw013b! \
                                    \dj3b1!killer!toma
                                    /
           drillsys!infoswx!convex!/

Tom Armistead

chris@umcp-cs.UUCP (Chris Torek) (06/22/86)

[I could swear this has been answered before, but here goes:]
In article <237@killer.UUCP> toma@killer.UUCP (Tom Armistead) writes:
>The delima - Is it possible to cast a 'pointer to' a function?

Possible: yes; portable: no.

>What I have is a char * that holds the address of a function.
>int	foo();
>char	*addr = foo;
>Would it be possible to call the function foo() via the variable addr?

Technically, that should be `char *addr = (char *) foo;'.  If this happens
not to lose important information, you can subsequently successfully use

	value = (*(int (*)())addr)(arg1, arg2, ...);

The cast `(int (*)())', odd-looking though it may be, coerces the type
to `pointer to function returning int'.

>Secondly is it possible to have an array of type 'pointer to' function.
>i.e. 
>int  (*function)()[SIZE];

Certainly it is possible; you just need to construct the proper
declaration.  For example, feeding the description

	declare f as array 10 of pointer to function returning int

through cdecl produces

	int (*f[10])()

There are at least two programs that do what cdecl does; as I recall,
the one I do not have was posted less than three months ago to either
net.sources or mod.sources.  Cdecl itself was posted to net.sources
over a year ago.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

gwyn@brl.arpa (VLD/VMB) (06/22/86)

Although many C implementations will allow one to store function
addresses in other types of pointers, such as (char *), it is not
guranteed.  Indeed, as I recall the latest X3J11 Draft it is not
guaranteed even for (void *), the "generic" object pointer type.

It is easy to get an array of function pointers.  Just declare them
properly (taking C operator precedence and associativity into account):

	void (*funcp[100])();	/* array of 100 ptrs to funcs */

	(*funcp[9])( args );	/* invokes the 10th function */

latham@bsdpkh.UUCP (06/24/86)

In article <237@killer.UUCP> toma@killer.UUCP (Tom Armistead) writes:
>The delima - Is it possible to cast a 'pointer to' a function?
>
>What I have is a char * that holds the address of a function.
>int	foo();
>char	*addr = foo;
>Would it be possible to call the function foo() via the variable addr?
>
>Secondly is it possible to have an array of type 'pointer to' function.
>i.e. 
>int  (*function)()[SIZE];
>something like the above, I was able to achieve this using this:
... etc
>Thanx in advance for **ANY** help,
>
>Tom Armistead

FIRST, char *addr = foo;  is a BAAADDDD idea! and NO you can't call foo with it
   ( well you can but .... )

Try, 
	int (* addr)() = foo;

or in general :

	int (* funcptr)();

SECOND an array of such pointers is declared :

	int (* funcptr[])();

	(* funcptr[])  being an array of pointers;
	(* funcptr[])()  ... to functions;
	int (* funcptr[])(); returning an integer;

A BETTER IDEA is to declare 'funcptr' as a type

	typedef int (* funcptr)();

then use it ...

	funcptr foo[1028];

This is much clearer.

incidentally,    ( (int *())addr)();  would do it     (I think?)


			Ken Latham, AT&T-IS (via AGS Inc.), Orlando , FL

			uucp: ihnp4!bsdpkh!latham

sbanner1@uvicctr.UUCP (sbanner1) (06/25/86)

In article <237@killer.UUCP> toma@killer.UUCP (Tom Armistead) writes:
>Secondly is it possible to have an array of type 'pointer to' function.

Yes, It is possible, though I don't remember the details.  A freind of
mine wrote a program to convert ASCII carage control to IBM/Fortran
carage control, where he read a character, and called the function
indexed by it in the array.  I have the source for it somewhere if
you are interested.  It works great on our Pyramid where the function
call overhead is low, but slows down on our 780, and the IBM PC clone
I have at home.

                     Hope this helps,

                          S. John Banner

Disclamer : I am not in any way affiliated with any of the manufacturers
listed above, except in that I am a user of them all.  The opinions I
have experessed may not nessasarily reflect the veiws of anyone else
at this establishment.

!uw-beaver!uvicctr!sbanner1   UUCP.
ccsjb@uvvm    BITNET.

nz@wucs.UUCP (Neal Ziring) (06/26/86)

In article <237@killer.UUCP> toma@killer.UUCP (Tom Armistead) writes:
 > The delima - Is it possible to cast a 'pointer to' a function?
 > What I have is a char * that holds the address of a function.
 > int	foo();
 > char	*addr = foo;
 > Would it be possible to call the function foo() via the variable addr?

Not sure about this, but I think    
				  i = ( int (*)())addr(arg1,arg2,arg3);
will work.

 > Secondly is it possible to have an array of type 'pointer to' function.
 > i.e. 
 > int  (*function)()[SIZE];
 > something like the above, I was able to achieve this using this:
 > struct	fct {
 >             int  (*func)();
 >             } f_array[SIZE];
 > Is there another way???

Yes, you can declare the array directly, and even initialize it.

int do_err();
int do1();
int do2();

int (*f_array[])() = { do_err, do1, do2 };


 > Thanx in advance for **ANY** help,
 > - Tom

Get cdecl!  That is the program I used to get the declarations above.
It is a neat program that translates between ~English and C declarations.

-- 
...nz (Neal Ziring at WU ECL  -  we're here to provide superior computing.)

	{seismo,ihnp4,cbosgd}!wucs!nz   OR   nz@wucs.UUCP

    "You could get an infinite number of wires into this !*$$#!?! junction 
                         box, but we usually don't go that far in practice"
				--   Employee of London Electricity Board, 1959

levy@ttrdc.UUCP (Daniel R. Levy) (06/27/86)

In article <1688@wucs.UUCP>, nz@wucs.UUCP writes:

>Get cdecl!
>It is a neat program that translates between ~English and C declarations.

Someone, please, tell me how I can go about getting cdecl for SysVR2.  Is
it available from mod.sources?  (Past queries to mod.sources have apparently
never reached the moderator.)  Or is it for sale (from whom?).  Thanks.

Dan.
ihnp4!ttrdc!levy

kk@amdcad.UUCP (Krishnakumar K.) (06/30/86)

In article <237@killer.UUCP> toma@killer.UUCP (Tom Armistead) writes:
>Secondly is it possible to have an array of type 'pointer to' function.
>i.e. 
>int  (*function)()[SIZE];
>something like the above, I was able to achieve this using this:
>struct	fct {
>            int  (*func)();
>            } f_array[SIZE];
>function()
>{
>    int x;
>    printf("offset: ");
>    scanf("%d",&x);
>    (*f_array[x].func)();
>}
>Is there another way???
>
I'm currently involved in writing an interpreter to process numeric 
expressions.  When I encounter a function reference I need to translate
between that string and the 'C' function that will perform it.  The
following seems to work well.  I use a binary search of a function
table to keep it fast even for a large number of possible functions.

typedef struct {
	char *funcname;
	double (*func)();
} FUNCELEM;

extern double exp(), log(), sin(), cos();

FUNCELEM functable[] = {
	{ "cos", cos },
	{ "exp", exp },
	{ "log", log },
	{ "sin", sin }
};

extern double (*binary_search())();

double callfunc(name, arg) 
char *name;
double arg;
{
	double (*func)();

	func = binary_search(functable, name);
	if (func == NULL)
		return 0.0;
	else
		return (*func)(arg);
}

Brad Budlong.

meissner@dg_rtp.UUCP (Michael Meissner) (06/30/86)

In article <1688@wucs.UUCP> nz@wucs.UUCP (Neal Ziring, 1 > ) writes:
>
>In article <237@killer.UUCP> toma@killer.UUCP (Tom Armistead, 2 >'s) writes:
> > The delima - Is it possible to cast a 'pointer to' a function?
> > What I have is a char * that holds the address of a function.
> > int	foo();
> > char	*addr = foo;
> > Would it be possible to call the function foo() via the variable addr?
>
>Not sure about this, but I think    
>				  i = ( int (*)())addr(arg1,arg2,arg3);
>will work.

    Note under ANSI C it  ill not be possible to cast pointers to functions
(except maybe to other pointer's to functions) to/from other data types.  This
is because functions are not objects (yes I know functions are objects in LISP,
but the current topic is C).  The reason for this is that a pointer to a
function may be wider than a corresponding pointer to an object, to support
things like overlays, far calls, etc.

	Michael Meissner, Data General
	...{ decvax, ucbvax, ihnp4 }!mcnc!rti-sel!dg_rtp!meissner

aka@cbrma.UUCP (Andy Kashyap) (07/01/86)

In article <237@killer.UUCP> toma@killer.UUCP (Tom Armistead) writes:
>Secondly is it possible to have an array of type 'pointer to' function.
>i.e. 
>int  (*function)()[SIZE];
>something like the above, I was able to achieve this using this:
>struct	fct {
>            int  (*func)();
>            } f_array[SIZE];
>function()
>{
>    int x;
>    printf("offset: ");
>    scanf("%d",&x);
>    (*f_array[x].func)();
>}
>Is there another way???
>

Yes.

Declare as thus:
    int (*function[SIZE])() ;

Set as thus:
    function[i] = printf ;

Invoke as thus:
    (*function[i])("hello world\n") ;

				- Andy Kashyap
				- ..!cbosgd!cbrma!aka

pjc@ptsfa.UUCP (Paul Condie) (07/04/86)

Example of pointers to functtions:

#include <stdio.h>
typedef int FCH();
typedef FCH *pFCH;

main()
{
   int   	Function1(), Function2(), Function3();
   static pFCH	Farray[]= { Function1, Function2, Function3 };

   (*Farray[0])();
   (*Farray[1])();
   (*Farray[2])();
}

Function1()
{   printf ("\nExecuting function 1"); }

Function2()
{   printf ("\nExecuting function 2"); }

Function3()
{   printf ("\nExecuting Function 3"); }

/* 
** Paul J. Condie
** 415/545-8371
** {ihnp4,qantel}!ptsfa!pbbahd!pbpjc!pjc
*/

apc@cbuxb.UUCP (Alan Curtis) (07/06/86)

>Secondly is it possible to have an array of type 'pointer to' function.
Ok, on my machine this works:

hi(a)	{
	return(2*a);
	}

by(a)	{
	return(4*a);
	}

int (*(func[2]))() = { hi, by };

main()
	{
	printf("0x%x, 0x%x, 0x%x, 0x%x.\n",
			func[0], func[1], (*func[0])(1), (*func[1])(1));
	}

To produce:

0x24, 0x30, 0x2, 0x4.

I assume this is what you where looking for??

Alan Curtis.