[comp.lang.c++] Pointers to functions

shopiro@alice.UUCP (Jonathan Shopiro) (08/30/88)

In article <8808271631.AA21050@explorer.dgp.toronto.edu>, flaps@dgp.toronto.edu (Alan J Rosenthal) writes:
> 
> ...
> While testing this, I found the compiler unwilling to take a local
> declaration of the form:
> 	int (*f)(int);

This question seems to come up pretty often.  The problem is a due to
a limitation of the compiler.  The solution is to use a typedef, e.g.,

	typedef int	FINT(int);
	FINT*	fp;

or

	typedef int	(*FINTP)(int);
	FINTP	fp1;

In the above, fp and fp1 have the same type.  I prefer the first method
because it seems simpler and I like to see stars where there are pointers.
-- 
		Jonathan Shopiro
		AT&T Bell Laboratories, Murray Hill, NJ  07974
		research!shopiro   (201) 582-4179

aj3u@wilbury.cs.virginia.edu (Asim Jalis) (05/15/91)

What is the difference between these two (pf is a pointer to a
function, and hello is a function):

pf = hello;	

and 

pf = &hello;

The definitions for pf and hello are as follows:

void (*pf)();	// pointer to a function

void hello()
{
  printf("Hello World\n");
}

I used the two different forms of assignments and got the same output.
Is there a difference between them?

Asim.

dave@cs.arizona.edu (Dave Schaumann) (05/15/91)

In article <AJ3U.91May14140642@wilbury.cs.virginia.edu> aj3u@wilbury.cs.virginia.edu (Asim Jalis) writes:
>What is the difference between these two (pf is a pointer to a
>function, and hello is a function):
>
>pf = hello;	
>
>and 
>
>pf = &hello;
>
>The definitions for pf and hello are as follows:
>
>void (*pf)();	// pointer to a function
>
>void hello()
>{
>  printf("Hello World\n");
>}
>
>I used the two different forms of assignments and got the same output.
>Is there a difference between them?

You have found one of the weirdnesses of ANSI-C.  When you have a pointer
to a function, you (normally) invoke the function by saying

	(*funptr)()

However, ANSI, in it's infinite wisdom, decided that you should be able to
say

	funptr()

in the same context, with similar results.

---- Possible rationalization to follow ... press 'n' if you don't care ----

Actually, I believe this is probably due to an influence from C++, where you
have constructs called "classes" (which are similar in some ways to structs).
Suppose you have a class "foo", with an function called "foo_fn".  Now, you
declare v to be a variable of class foo:

  foo v ;

You now can invoke the function foo_fn on v in the following manner:

  v.foo_fn()

(A pointer to v is an implicit variable in the function call)

This functionality can be mimiced in C in the following manner:

typedef struct FOO {
  ...
  void (*foo_fn) ( struct FOO * ) c;
  ...
  } foo ;

foo v ; /* assume that v.foo_fn is initialized appropriately */

Now, according to the traditional interpretation, you must say

  (*v.foo_fn)(&v) ; /* A ptr to v must be explicitly passed */

To invoke foo_fn on v.  The new interpretation allows you to say

  v.foo_fn(&v) ;

Almost like C++ (almost since you still have to explicitly pass a
pointer to the invoking "variable" (known as "self" in C++)).  Thus,
this feature allows you some measureof "poor man's C++" in ANSI C.
Of course, many of the nice features of C++ must be done by hand...

-- 
Dave Schaumann      | There is no cause so right that one cannot find a fool
dave@cs.arizona.edu | following it.	- Niven's Law # 16

steve@taumet.com (Stephen Clamage) (05/15/91)

aj3u@wilbury.cs.virginia.edu (Asim Jalis) writes:

>What is the difference between these two (pf is a pointer to a
>function, and hello is a function):

>pf = hello;	
>and 
>pf = &hello;

There is no difference.  The oddity is this:  A function designator
appearing in an expression context is replaced by the address of the
function, making a pointer-to-function.  Attempts to take the address
of the function designator are ignored. So
	hello
	&hello
	&&&&&&&&&&&&&&&&hello
are all equivalent.

Similarly, when you dereference a pointer-to-function, you get a
function designator, which is replaced by pointer-to-function.
Consequently,
	pf()
	(*pf)()
	(****************pf)()
are all equivalent.

-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

gdtltr@brahms.udel.edu (gdtltr@limbo.org (The Befuddled One)) (05/16/91)

In article <730@taumet.com> steve@taumet.com (Stephen Clamage) writes:
=>	hello
=>	&hello
=>	&&&&&&&&&&&&&&&&hello
=>are all equivalent.
=>
   Except that the last one is illegal. The result of &hello is not
an lvalue, so & can't be applied to it.

                                        Gary Duzan
                                        Time  Lord
                                    Third Regeneration



-- 
                            gdtltr@brahms.udel.edu
   _o_                      ----------------------                        _o_
 [|o o|]   Two CPU's are better than one; N CPU's would be real nice.   [|o o|]
  |_o_|           Disclaimer: I AM Brain Dead Innovations, Inc.          |_o_|

bhoughto@pima.intel.com (Blair P. Houghton) (05/16/91)

In article <1512@caslon.cs.arizona.edu> dave@cs.arizona.edu (Dave Schaumann) writes:
>You have found one of the weirdnesses of ANSI-C.  When you have a pointer
>to a function, you (normally) invoke the function by saying
>	(*funptr)()
>However, ANSI, in it's infinite wisdom, decided that you should be able to
>say
>	funptr()
>in the same context, with similar results.

It's not weird at all.  It's rather consistent.  The actual
syntax is

	<expression>(<optional list of arguments>)

where the expression must evaluate to a function pointer.
A similar thing is true of arrays, structs, and unions, where
the syntaxes are

	<expression>[<expression>]
	<expression>.<member name>
	<expression>-><member name>

The only thing remotely weird about it is that now `funptr'
and `*funptr' are the same thing, but that's why function
poiners are often singled out for different semantic
treatment in the standard (many things you can do with
a pointer to int are forbidden with a function pointer).

				--Blair
				  "Many things you can do with
				   your own nose are forbidden
				   with your neighbor's."

dpg@extro.ucc.su.OZ.AU (D P Gilbert) (05/17/91)

bhoughto@pima.intel.com (Blair P. Houghton) writes:

>In article <1512@caslon.cs.arizona.edu> dave@cs.arizona.edu (Dave Schaumann) writes:
>>You have found one of the weirdnesses of ANSI-C.  When you have a pointer
>>to a function, you (normally) invoke the function by saying
>>	(*funptr)()
>>However, ANSI, in it's infinite wisdom, decided that you should be able to
>>say
>>	funptr()
>>in the same context, with similar results.

>It's not weird at all.  It's rather consistent.  The actual
>syntax is

>	<expression>(<optional list of arguments>)

>where the expression must evaluate to a function pointer.
>A similar thing is true of arrays, structs, and unions, where
>the syntaxes are

>	<expression>[<expression>]
>	<expression>.<member name>
>	<expression>-><member name>

>The only thing remotely weird about it is that now `funptr'
>and `*funptr' are the same thing, but that's why function
>poiners are often singled out for different semantic
>treatment in the standard (many things you can do with
>a pointer to int are forbidden with a function pointer).

As I reach for the shift button to put yet another set of left and
right parentheses after a niladic function call I have begun to
wonder how to relieve such tedium. Wouldn't it be nice just to
write the function name without those parentheses (e.g. token.get
instead of token.get() ). The syntax of C tells me why but could it
be bent with a #pragma perhaps? Whenever I want the address of a
function I use "&" so I can understand my code 18 months later.

I know this amounts to heresy ... apologies in advance
Doug Gilbert

comeau@ditka.Chicago.COM (Greg Comeau) (05/17/91)

In article <AJ3U.91May14140642@wilbury.cs.virginia.edu> aj3u@wilbury.cs.virginia.edu (Asim Jalis) writes:
>pf = hello;	and     pf = &hello;
>The definitions for pf and hello are as follows:
>void (*pf)();	// pointer to a function
>void hello() {   printf("Hello World\n"); }
>I used the two different forms of assignments and got the same output.
>Is there a difference between them?

There is a difference even though they both end up at the same.

In 'pf = hello;', the function name expression is implicitly converted into
a pointer to a function of the appropriate type (a void(*)()) when in this
context.

With 'pf = &hello;', since the operand of & is a function, it is a pointer
to a function of the appropriate type.  It does not become a pointer to a
pointer to a function.

The C++ style is to use the & form.

- Greg
-- 
	 Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418
                          Producers of Comeau C++ 2.1
          Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421
                     Voice:718-945-0009 / Fax:718-441-2310

bhoughto@pima.intel.com (Blair P. Houghton) (05/18/91)

In article <dpg.674453898@extro> dpg@extro.ucc.su.OZ.AU (D P Gilbert) writes:
>Wouldn't it be nice just to write the function name
>without those parentheses (e.g. token.get instead of
>token.get() ).
>I know this amounts to heresy ... apologies in advance

Ob. response:

	If you want Pascal, you know where to find it.

				--Blair
				  "I don't want it, and come
				   to think of it, I don't
				   know where to find it..."

enag@ifi.uio.no (Erik Naggum) (05/20/91)

D P Gilbert writes:
|
|   As I reach for the shift button to put yet another set of left and
|   right parentheses after a niladic function call I have begun to
|   wonder how to relieve such tedium. Wouldn't it be nice just to
|   write the function name without those parentheses (e.g. token.get
|   instead of token.get() ). The syntax of C tells me why but could
|   it be bent with a #pragma perhaps? Whenever I want the address of
|   a function I use "&" so I can understand my code 18 months later.

Assuming

	struct ... {
		...
		void (*get)();
		...
	} token;

token.get() is a function call by virtue of the "()", while
token.get is the value of the function pointer.

Remember that statements such as

	3;

are legal in C, but sort of pointless.

	token.get;

is no exception.

Other languages don't know about function pointers and can alleviate
the user of the power thereof.

</Erik>
--
Erik Naggum             Professional Programmer            +47-2-836-863
Naggum Software             Electronic Text            <enag@ifi.uio.no>
0118 OSLO, NORWAY       Computer Communications      <erik@naggum.uu.no>