[comp.lang.c] indirect reference/use of procedures

cynthia@ucselx.sdsu.edu (cynthia Anderson) (03/09/90)

hello

i would like to be able to write a procedure that takes as
a parameter a procedure name and then using that name
calls the procedure.

ie  runAProcedure(myProcedure)
   {


	myProcedure


}

Is this possible to do in C?  Any help or advise is appreciated
tho please e-mail responses so the net won't be cluttered.

thanks,

cynthia anderson
<cynthia@cod.nosc.mil.uucp>
or
<cynthia@ucselx.sdsu.edu>

Disclaimer: whenever it was and whenever it happened, i'm sure i 
wasn't there and it couldn't have been me.

Lynn.Lively@p4694.f506.n106.z1.fidonet.org (Lynn Lively) (03/13/90)

In an article of <9 Mar 90 04:51:51 GMT>, cynthia@ucselx.sdsu.edu (cynthia Anderson) writes:

 cA>From: cynthia@ucselx.sdsu.edu (cynthia Anderson)
 cA>Date: 9 Mar 90 04:51:51 GMT
 cA>Organization: San Diego State University Computing Services
 cA>Message-ID: <1990Mar9.045151.9601@ucselx.sdsu.edu>
 cA>Newsgroups: comp.lang.c
 cA>
 cA>hello
 cA>
 cA>i would like to be able to write a procedure that takes as
 cA>a parameter a procedure name and then using that name
 cA>calls the procedure.
 cA>
 cA>ie  runAProcedure(myProcedure)
 cA>   {
 cA>
 cA>
 cA>        myProcedure
 cA>
 cA>
 cA>}
 cA>
 cA>Is this possible to do in C?  Any help or advise is appreciated
 cA>tho please e-mail responses so the net won't be cluttered.
 cA>
 cA>thanks,
 cA>
 cA>cynthia anderson
 cA><cynthia@cod.nosc.mil.uucp>
 cA>or
 cA><cynthia@ucselx.sdsu.edu>
 cA>
 cA>Disclaimer: whenever it was and whenever it happened, i'm sure i 
 cA>wasn't there and it couldn't have been me.
 cA>t

 Cynthia,
     Not only is it possible it's actually fairly easy to do. You need to  
declare your function in the following form.

<returntype> (* funcname) ();

Examples:

int  (* myfunc)();
void (* myfunc)();

use it in the program like this

myfunc ();

If it uses parameters simply specify them at call time.

myfunc (param1, param2);

of course my the declaration is only a pointer so make sure you initialize it  
to something. Hence you could do this.

int (* myprint) () = printf;

myprint ("Hello World!\n");

You can also set up tables of them if you like.

typedef INTFUNC int (* func)();

INTFUNC func_tab[10];

and later on refer to 

func_tab[1]();

Hope this helps.

 Your Servant,
      Lynn



 

peter@ficc.uu.net (Peter da Silva) (03/16/90)

> void (* myfunc)();

> myfunc ();

I realise this is a valid syntax as of X3J11 (or whatever it is now that
it's complete), but it's confusing. If nothing else, it breaks the symmetry
between usage and declaration. C declaration syntax is confusing enough
as it is, and declarations of pointers to functions particularly so. It's
better to blow the extra three characters and call "(* myfunc) ();".

What did the committee have in mind when they decided to make this syntax
part of the standard?
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

scjones@sdrc.UUCP (Larry Jones) (03/19/90)

In article <A392C67xds13@ficc.uu.net>, peter@ficc.uu.net (Peter da Silva) writes:
> > void (* myfunc)();
> 
> > myfunc ();
> 
> I realise this is a valid syntax as of X3J11 (or whatever it is now that
> it's complete), but it's confusing. If nothing else, it breaks the symmetry
> between usage and declaration. C declaration syntax is confusing enough
> as it is, and declarations of pointers to functions particularly so. It's
> better to blow the extra three characters and call "(* myfunc) ();".
> 
> What did the committee have in mind when they decided to make this syntax
> part of the standard?

Would you believe => printf("Hello, world\n"); ?

Since "everyone knows" that you really use the address of a
function to call it (not the function itself), and since function
names usually turn into function pointers, it was far simpler to
specify that function "objects" "always" turn into function
pointers and that the function call operator requires a function
pointer.  It does make the call more readable, but it breaks the
declaration/use symmetry as you noted.

("Object" because functions are not, strictly speaking, objects,
and "always" because there is an exemption for sizeof.)
----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@SDRC.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"You know how Einstein got bad grades as a kid?  Well MINE are even WORSE!"
-Calvin

pmk@craycos.com (Peter Klausler) (03/20/90)

Larry Jones notes:
> Since "everyone knows" that you really use the address of a
> function to call it (not the function itself), and since function
> names usually turn into function pointers, it was far simpler to
> specify that function "objects" "always" turn into function
> pointers and that the function call operator requires a function
> pointer.  It does make the call more readable, but it breaks the
> declaration/use symmetry as you noted.

Section 3.2.2.1 says "Except when it is the operand of the sizeof operator or
the unary & operator, a function designator... is converted to an expression
that has type "pointer to function..."", and 3.3.3.2 notes "The unary *
operator denotes indirection. If the operand points to a function, the result
is a function designator." Thus, given a pointer to a function, you can stick
0 or more asterisks in front of the name during a call on the pointer; they're
all irrelevant. Example:

	void f (void) { printf ("Hello"); }
	void (*p)(void) = &f;
	main () { (******************************************************p)(); }

Strange.

-Peter Klausler, writing compilers at Cray Computer Corp. (not Cray Research)

sanders@sanders.austin.ibm.com (Tony Sanders) (03/20/90)

In article <A392C67xds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
-> void (* myfunc)();
-> myfunc ();
-
-I realise this is a valid syntax as of X3J11 (or whatever it is now that
-it's complete), but it's confusing. If nothing else, it breaks the symmetry
-between usage and declaration. C declaration syntax is confusing enough
-as it is, and declarations of pointers to functions particularly so. It's
-better to blow the extra three characters and call "(* myfunc) ();".
I agree on the point that usage and declaration should agree.  I'm 100%
supportive of using "(*myfunc)();".  I used "myfunc()" a few times in
the past and it's confusing when trying to debug that code.  I keep
looking for a function named "myfunc" and sometimes it can take a few
minutes to realize what I've done, I then convert the code before it
does anymore damage (don't you just hate old code :-).

-What did the committee have in mind when they decided to make this syntax
-part of the standard?
I suspect since it was already being used both ways, they simply decided
not to break existing code (which maybe wouldn't have been such a bad idea).
I just hope they clearly advocate the usage of "(*myfunc)()" in the standard.

-- sanders                          The 11th commandment: "Thou shalt use lint"
For every message of the day, a new improved message will arise to overcome it.
Reply-To: cs.utexas.edu!ibmaus!auschs!sanders.austin.ibm.com!sanders     (ugh!)

karl@haddock.ima.isc.com (Karl Heuer) (03/22/90)

In article <1205@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes:
>In article <A392C67xds13@ficc.uu.net>, peter@ficc.uu.net (Peter da Silva) writes:
>>[an ANSI function-pointer can be invoked with pf() as well as (*pf)()]
>>What did the committee have in mind when they decided to make this syntax
>>part of the standard?
>
>Would you believe => printf("Hello, world\n"); ?
>
>Since "everyone knows" that you really use the address of a function to call
>it (not the function itself), and since function names usually turn into
>function pointers, it was far simpler to specify that function "objects"
>"always" turn into function pointers and that the function call operator
>requires a function pointer.

There are two ways to state the new rules: (a) Function lvalues decay into
pointer rvalues even when used in a function-call context; the function-call
operator expects a function-pointer operand (usually resulting from such a
decay).  (b) Function lvalues are insulated from such decay when used in a
function-call context; the function-call operator expects its operand to have
function type.  As a special case, a function-pointer used in such a function
context will automatically be dereferenced.

These two variants specify identical syntax and semantics, so they are equally
"correct", although (a) is the one actually used in the ANS.  (b) is the
pre-ANSI specification, except that the last sentence is a Common Extension
rather than a required rule.

My preference would have been to keep system (b), without the special case,
*and* to deprecate the existing rule that function lvalues automatically decay
into pointer rvalues.  Thus, the approved style would be
	pf = &f; /* not "pf = f;" */
	(*pf)();
which would improve the purity of the type system.

I think I did submit this one to X3J11.  They weren't too enthusiastic.  (This
was one of several things that *could* have been "fixed", but only in the long
run, by deprecating what is now a commonly used syntax; the Committee was much
more pessimistic about such things than I.)

Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint