void * = pointer to a function

GEOFFREY TOBIN, ELECTRONIC ENGINEERING ECSGRT at lure.latrobe.edu.au
Wed Mar 13 06:06:47 AEST 1991


In article <27385 at uflorida.cis.ufl.EDU>, pm0 at reef.cis.ufl.edu (Patrick Martin) writes:
 
> main()
> {
>    void *Function = (int (*) (int)) Output_Num;
          ^^^^^^^^^
          Mistake here.

>    (*Function) (5);
       --------
       VAX C 3.1 compiler complains here.
> }

The mistake was to use an ordinary void pointer in place of a function
pointer.  The compiler isn't impressed that you called it "Function",
either, even though this fools the human eye.

I declared Function as follows, and VAX/VMS C 3.1 was content.

main()
{
   void (*Function)() = (int (*) (int)) Output_Num;
   (*Function) (5);
}

The cast is also unnecessary (at least in VAX/VMS C 3.1).  The compiler
was also completely satisfied with:

void (*Function)() = Output_Num;

I think that in the ANSI standard for C, void pointers (and their
elaborations, such as void function pointers) may be assigned from other
pointers.  The exact rules I forget.  For portability of your programs,
I recommend that you find out.  (Talk about "Do as I say..."! :-)

> What would the code look like if the function were:
> 
> void Hello_World() {printf("Hello world")}
> 
> main()
> {
>    void *F = (void (*) (void)) Hello_World;  /* () for (void) ? */
           ^
           You did it again.  A void pointer is not a function pointer.
A void pointer is a variable that contains an address.  No other
information is associated with it, because the "void" type has no
constants, so no values, so no variables.  ("void" is like the empty
set in math.)  Consequently, it is illegal to dereference F as "*F",
as F is here (as C understands it) an address without any contents.
All you can do with such an F is to print it using "%p", subtract
and add integers to it, assign it, cast it, and compare it with
other pointers.  (Any other possibilities, people?)

Instead, you may write (in VAX/VMS C 3.1, for example) :

	void (* F) () = Hello_World;

Now, regarding your next question:
In a K&R first-edition C compiler, "void" is never necessary; indeed,
in some older compilers, "void" may be rejected as unknown.  In ANSI C,
the inclusion of "void" is clearer, and in certain circumstances it is
required.

>    (*F) ();  /* or should the call be (*F) (void) ? */

The former is correct.  We don't write "g(void)" for the call of a
function with no arguments, for the same reason that we don't write
"max (int a, int b);" or "int max (int a, int b);" for the call of
a function of two arguments:  "void" is a type, not an argument list.

If my explanation is unclear, please express your doubts.
For other readers (or yourself later), if my explanations are wrong,
please flame away!

Yours sincerely,
Geoffrey Tobin



More information about the Comp.lang.c mailing list