From: porkchop@invalid.foo   
      
   On Fri, 02 Jan 2026 02:52:22 -0800, Keith Thompson wrote:   
      
   > Michael Sanders writes:   
   >> i have:   
   >>   
   >> void moo(char HISTORY[][64], int hst_len, int invalid, const char *gme_msg)   
   >>   
   >> void mastermind(char HISTORY[][64], int hst_len, int invalid, const char   
   *gme_msg)   
   >>   
   >> to use either i have:   
   >>   
   >> void (*render)(char [][64], int, int, const char *) = MOO ? moo :   
   mastermind;   
   >>   
   >> my multi-part question:   
   >>   
   >> why is void required for the function pointer?   
   >   
   > Every function has a type. Every function pointer has a type. For a   
   > function pointer to point to a function, it must have type "pointer to   
   > blah", where "blah" is the type of the function.   
   >   
   > A function type includes information about the type of the function's   
   > result and the types of its parameters. The type of both foo and   
   > mastermind can be written as:   
   >   
   > void(char[]64], int, int, const char*)   
   >   
   >> A: because both moo() & mastermind return void?   
   >   
   > Yes.   
   >   
   >> B: because every function must have a return type   
   >> *including function pointers*?   
   >   
   > Functions and function pointers are of course distinct. A function is   
   > of function type. A function pointer is of an object type, specifically   
   > a pointer-to-function type.   
   >   
   > Every pointer-to-function type is derived from a function type, and that   
   > function type specifies the type returned by the function -- "void" in   
   > this case.   
   >   
   >> C: what about tyedef?   
   >   
   > What about it?   
   >   
   > You can define a typedef for the function type, which could make the   
   > code a bit simpler. (It's also common to define a typedef for a   
   > pointer-to-function type, but I prefer to typedef the function type   
   > itself.)   
   >   
   > An example based on your code :   
   >   
   > ```   
   > #include    
   >   
   > void moo(char HISTORY[][64], int hst_len, int invalid, const char *gme_msg) {   
   > puts("moo");   
   > }   
   >   
   > void mastermind(char HISTORY[][64], int hst_len, int invalid, const char   
   *gme_msg) {   
   > puts("mastermind");   
   > }   
   >   
   > typedef void functype(char [][64], int, int, const char *);   
   >   
   > int main(void) {   
   > for (int MOO = 0; MOO < 2; MOO ++) {   
   > functype *render = MOO ? moo : mastermind;   
   > printf("MOO is %s: ", MOO ? "true" : "false");   
   > render(NULL, 0, 0, "");   
   > }   
   > }   
   > ```   
   >   
   > The output :   
   >   
   > ```   
   > MOO is false: mastermind   
   > MOO is true: moo   
   > ```   
   >   
   > (Incidentally, all-caps identifiers are most commonly used as macro   
   > names, with FILE being a notable exception.)   
      
   Excellent reply, appreciate it (especially examples).   
      
   --   
   :wq   
   Mike Sanders   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|