Path: utzoo!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!usc!samsung!munnari.oz.au!ariel!ucsvc.ucs.unimelb.edu.au!lu!ecsgrt From: ECSGRT@lure.latrobe.edu.au (GEOFFREY TOBIN, ELECTRONIC ENGINEERING) Newsgroups: comp.lang.c Subject: Re: void * = pointer to a function Message-ID: <5143@lure.latrobe.edu.au> Date: 12 Mar 91 20:06:47 GMT References: <27385@uflorida.cis.ufl.EDU> Distribution: comp.lang.c Organization: VAX Cluster, Computer Centre, La Trobe University Lines: 76 In article <27385@uflorida.cis.ufl.EDU>, pm0@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