Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uflorida!haven!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.std.c Subject: Re: Question about function pointers & prototypes Message-ID: <19278@mimsy.UUCP> Date: 26 Aug 89 19:04:23 GMT References: <1611@agora.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 68 In article <1611@agora.UUCP> rickc@agora.UUCP (Rick Coates) writes: >I am using an array of pointers to functions to access procedures. My >compiler complains about lacking a function prototype. Since the >procedures take from none to four differing parameters, how do I declare it? >Just as if it has variable arguments? I'd have to look up how one declares >no or more arguments... The proposed standard seems (meaning `you should check this yourself') to require that all function pointers `fit' in some other function pointer storage cell. You must, however, cast these pointers back to their proper type before calling the functions retained. That being the case, you can do something like this: /* * basic_fptr is a basic function-pointer type: it is a * pointer to a function of no arguments that returns void. */ typedef void (*basic_fptr)(void); /* this is syntactic sugar to make the table look pretty */ #define C(x) (basic_fptr)(x) /* here are the functions that go in the table */ int f1(int a, char *b); void f2(void); double f3(double x); /* more as desired */ /* here is the table itself */ struct ftable { char *ft_name; /* the name */ basic_fptr ft_fn; /* the pointer */ char *ft_type; /* remembers type of fn & args */ } ftable[] = { "f1", C(f1), "int(int,char*)", /* the C() cast is not necessary on f2, but this looks symmetric */ "f2", C(f2), "void()", "f3", C(f3), "double(double)", /* more as desired */ 0, 0, 0 /* end */ }; ... /* many lines later */ ... for (p = ftable; p->ft_name != NULL; p++) if (strcmp(name, p->ft_name) == 0) break; if (p->ft_name == NULL) { error("not found"); return (-1); } if (strcmp(p->ft_type, "void()") == 0) { p->ft_fn(); /* basic type is already void(void) */ return (0); } if (strcmp(p->ft_type, "int(int,char*)" == 0) return ((int(*)(int,char*))p->ft_fn)(intarg, cparg); if (strcmp(p->ft_type, "double(double)") == 0) { return ((double(*)(double))p->ft_fn)(dblarg) > 0.0; panic("what a strange function! (%s)", p->ft_type); /* NOTREACHED */ For efficiency, you might want to use `magic number' values in the ft_type field (since you can then switch() on it). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris