kdq@demott.COM (Kevin D. Quitt) (06/26/90)
I'm invoking functions through an array of struct. My compiler generates a warning in the following two cases. How do I declare prototypes given: ---------------- Example 1 -------** in the .h file: struct token_def { u16 index; u16 match; /* # of chars to match, 0 = all */ u8 name[16]; i16 (*fn)(); /* Function to call */ }; -------** in the configuration file: struct token_def configuration[] = { { TITLES, 0, "TITLES", paint_titles }, { REPAINT, 0, "REPAINT", collect_repaints }, { PBLOCK, 7, "PBLOCK_", define_pblock }, { TBLOCK, 7, "TBLOCK_", define_tblock }, { UPPER, 0, "UPPER", define_upper_platen }, { LOWER, 0, "LOWER", define_lower_platen }, { TOOL, 0, "TOOL", define_tool_probes } }; -------** in the code file: extern struct token_def configuration[]; ----** then, this: (*configuration[ tnum ].fn)( cfg, token ); ----** gets: pm.c(330) : warning C4071: 'configuration' : no function prototype given ---------------------------------------------------------------- #2 struct parse_info { CMD_IN *pici; /* Ptr to command input struct */ u16 piexcl; /* Boolean - exclusive command list */ u8 *piparam; /* Ptr to parameter string */ u16 piplen; /* Length of parameter(s) */ }; #define MAX_PARSE_DEPTH (16) local struct parse_info pi[ MAX_PARSE_DEPTH ]; ----** this: (*(pi[0].pici->func))(); ----** gets: input.c(762) : warning C4071: 'function through ptr' : no function prototype given Note also that depending upon the circumstances, the call will have zero, one or two parameters. -- _ Kevin D. Quitt demott!kdq kdq@demott.com DeMott Electronics Co. 14707 Keswick St. Van Nuys, CA 91405-1266 VOICE (818) 988-4975 FAX (818) 997-1190 MODEM (818) 997-4496 PEP last 96.37% of all statistics are made up.
karl@haddock.ima.isc.com (Karl Heuer) (07/01/90)
In article <326@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes: >I'm invoking functions through an array of struct. My compiler generates >a warning in the following two cases. How do I declare prototypes given: > (*configuration[ tnum ].fn)( cfg, token ); Change the struct definition: struct token_def { ... i16 (*fn)(cfg_t, token_t); } where cfg_t and token_t are the types of the arguments. > struct parse_info { CMD_IN *pici; ... } > (*(pi[0].pici->func))(); Similarly, use a prototype for the `func' member of the struct you've typedef'd to `CMD_IN'. > Note also that depending upon the circumstances, the call will have >zero, one or two parameters. Oh, that makes it a bit trickier. I presume the individual functions are not variadic (since you want to be able to pass zero args), and you just want to be able to store them all in the same structure type. Okay, then, the proper way to do it is to cast the constants to a common type in the initializer, and cast them back to the correct type before using them: struct token_def { ... void (*fn)(void); }; struct token_def configuration[] = { { TITLES, 0, "TITLES", (void (*)(void))paint_titles }, }; (*(i16 (*)(cfg_t, token_t))configuration[ tnum ].fn)( cfg, token ); Any function-pointer type may be used for the generic pointer; I used the simplest, `void (*)(void)'. You may want to use a typedef for this and the other function-pointer types. Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint