rickc@agora.UUCP (Rick Coates) (08/26/89)
I was using my more-or-less ANSI C compiler (Microsoft C for the PC), and ran across a question about function prototyping: 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... How about returns? Can I have some void, and some return an int? Sorry if is this is too elementary for this newsgroup... I was just wondering. Rick Coates ...!tektronix!reed!percival!agora!rickc
tneff@bfmny0.UUCP (Tom Neff) (08/26/89)
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? If the list of function pointers is such that the Nth entry is always a function of a certain declaration, while the N+1th is always a function of a certain OTHER declaration, etc., then it is probably better to use a structure here than an array. The structure declaration will let you provide explicit prototypes for the component function (pointers). If one or more entries in the list really do take a variable number of parameters, then the standard pANS "varargs" can be used in their declaration within the structure. This is a standard solution for installable drivers and the like. -- "We walked on the moon -- (( Tom Neff you be polite" )) tneff@bfmny0.UU.NET
chris@mimsy.UUCP (Chris Torek) (08/27/89)
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
gwyn@smoke.BRL.MIL (Doug Gwyn) (08/28/89)
In article <19278@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >The proposed standard seems (meaning `you should check this yourself') >to require that all function pointers `fit' in some other function pointer >storage cell. I don't recall any constraints that would imply this. Pointers to functions are far less "flexible" than object pointers.
bill@twwells.com (T. William Wells) (08/29/89)
In article <10835@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: : In article <19278@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: : >The proposed standard seems (meaning `you should check this yourself') : >to require that all function pointers `fit' in some other function pointer : >storage cell. : : I don't recall any constraints that would imply this. Pointers to : functions are far less "flexible" than object pointers. One can cast any function pointer to another and back again, and use the result. I've buried my dpANS so I can't quote chapter and verse but this was discussed a while ago here. --- Bill { uunet | novavax | ankh | sunvice } !twwells!bill bill@twwells.com
dfp@cbnewsl.ATT.COM (david.f.prosser) (08/29/89)
In article <10835@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >In article <19278@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >>The proposed standard seems (meaning `you should check this yourself') >>to require that all function pointers `fit' in some other function pointer >>storage cell. > >I don't recall any constraints that would imply this. Pointers to >functions are far less "flexible" than object pointers. Section 3.3.4, page 47, lines 4-7: A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function that has a type that is not compatible with the type of the called function, the behavior is undefined. Thus all function pointers are mutually convertible. They are, as Doug noted, not convertible to or from object pointers in any portable manner. Dave Prosser ...not an official X3J11 answer...