Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: function pointer question Date: Fri, 02 Jan 2026 02:52:22 -0800 Organization: None to speak of Lines: 86 Message-ID: <878qeguw0p.fsf@example.invalid> References: <10j7rs6$7c9e$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Fri, 02 Jan 2026 10:52:23 +0000 (UTC) Injection-Info: dont-email.me; posting-host="0c5ef296c1f282275d44508e0b1eb011"; logging-data="345807"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+8zgzBe3yhrqG/b6yKXU7r" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:WSRNSMmN0rGZ9Jz8ZWzmgjUT8v0= sha1:lkWd3dkhf4kMtS0zt3Udd5+E0kA= Xref: csiph.com comp.lang.c:396071 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.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */