void * = pointer to a function

Chris Torek torek at elf.ee.lbl.gov
Mon Mar 11 20:38:36 AEST 1991


In article <27385 at uflorida.cis.ufl.EDU> pm0 at reef.cis.ufl.edu
(Patrick Martin) writes:
>I am trying to get a grip on pointers to functions.  Here is
>the code I am having a problem with (Simplified to the bare
>essense of the problem)

There are several conceptual errors here.

[note, I have compressed the following vertically]
>#include <stdio.h>
>int Output_Num(int a) { printf("The Number is: %d",a); }
>main() {
>   void *Function = (int (*) (int)) Output_Num;
>   (*Function) (5);
>}

And:

>[if it were]
>void Hello_World() {printf("Hello world")}

[would it be]

>   void *F = (void (*) (void)) Hello_World;  /* can I use () in
>					        place of (void)? */
>   (*F) ();  /* or should the call be (*F) (void) */

The first error: to have a pointer to a function, you must declare an
object of type `pointer to function of ... returning T', where T is any
legal function-return type (i.e., a type that is not itself an array or
function type) and where `of ...' represent the number and types of
each argument.

In this case, you want:

	cdecl> declare Function as pointer to function (int) returning int
	int (*Function)(int)

and:

	cdecl> declare F as pointer to function (void) returning void
	void (*F)(void);

The second error: a cast is necessary only when you have a mismatch
between a value type and an object to which the value is to be assigned.
Even then the cast may be deleted under most circumstances:

	int i;
	i = (int) 3.141592653589793238462643383279502884;

The cast is unnecessary since conversion of floating point values to
integer values is `directly allowed'.

If you declare your function pointer correctly, you will not need a cast.

The third error (or not): a call through a pointer to a function is
pretty much identical to a `regular' call.  You would not write:

	main() { Hello_World(void); }	/* wrong */

in the second example, so you should not expect to write

	main() {
		void (*f)(void) = Hello_World;
		(*f)(void);		/* wrong */
		return 0;
	}

and instead you want just:

	main() {
		void (*f)(void) = Hello_World;
		(*f)();			/* right */
		return 0;
	}

ANSI C explicitly allows you to omit the `*' before the pointer:

	main() {
		void (*f)(void) = Hello_World;
		f();			/* right */
		return 0;
	}

Note that you *must* declare all functions before attempting to take
their addresses.  (Declaration via definition, as in the original two
examples, is fine.)  This is the same as having to declare variables
before taking their addresses; probably the only reason some people
find it confusing is that C allows you to *call* functions without
first declaring them.  (Some people, and some compilers, believe the
latter is a mistake and warn against it.)
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427)
Berkeley, CA		Domain:	torek at ee.lbl.gov



More information about the Comp.lang.c mailing list