Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!sdd.hp.com!hplabs!hpfcso!hpfcmdd!hpbbrd!hpbbn!hpcc05!aspen!hpcuha!hpda!hpcuhb!hpcllla!hplego!shankar From: shankar@hplego.HP.COM (Shankar Unni) Newsgroups: comp.lang.c++ Subject: Re: the SUN way.. *&$^#%) Message-ID: <67090001@hplego.HP.COM> Date: 2 Jan 91 22:38:57 GMT References: <1990Dec20.114821@roadster.bellcore.com> Organization: Hewlett Packard Calif. Language Lab Lines: 80 In comp.lang.c++, garnett@shera..bellcore.com (Michael Garnett) writes: } In article <3069@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes: } Q: I have used a "fully ANSI compliant" C compiler (I uassumed they were not } lying). The ANSI C prototype for bsearch looks just like the one I } suggested (and verifyed from the ObjectWorks\C++ search.h). ANSI C } will accept the compar function as is -- C++ will not. For C++ I *must* } accept const void*'s. This means that strcmp is not a valid compare } function for bsearch in C++, but it *IS* in ANSI C. (Hers's the Q): } Is my ANSI C compiler lenient? Am I correct that C++ will NOT accept } compare (const T*, const T*) ? This is a tricky question. Ron Guilmette is correct in saying that the types int (*)(void *) and int (*)(T *) are not compatible (in particular, the latter cannot be assigned to the former). The only rationale that I can think of is that if a function requires the former type as a parameter: foo(int (*p)(void *)) { } it might potentially call the argument "p" with *any* type of argumenty, whereas the actual function passed in to this parameter (your "compar()" function, for instance) is expecting only a "T *". Thus, making this restriction is one way of avoiding a runtime type mismatch. Unfortunately, as has been noted, this leaves us no way of defining a "generic function pointer", which, IMHO, is one of the serious omissions of the ANSI C standard and, unless someone (Ron, wanna volunteer? :-) makes a good proposal for it, of the forthcoming C++ standard as well. P.S. regarding the "laxness" of ANSI C compilers: many such compilers, recognizing the need for such a usage, are deliberately permissive on a mismatch of function pointer arguments, if the mismatch is between a "T *" and a "void *". } SUMMARY: } is 't1 (*)(...)' supposed to suspend the type-checking of parameter type } matching in pointer-to-function parameters? No. In fact, it is a very serious problem if there is a mismatch between a function with an ellipsis and one without (varargs functions have to be treated specially on many architectures). So this is the worst possible way to declare a generic function pointer. } If the 't1 (*)(...)' is forced, then what about ANSI's stdargs where } one needs at least one parameter to find the beginning of the variable } arguments? No function body should *ever* be defined with a "(...)" parameter list. The fact that C++ allows it is also, IMHO, a serious mistake. } I like the idea of a pointer to an unknown/undeterminable type, but why } can't void* serve this purpose? I assume that you mean "unknown/undeterminable function pointer type". Well, function and data pointers are explicitly kept apart, and never the twain shall meet (even with type casts). Think back to those ghastly DOS memory models (16-bit code and 32-bit data addresses, or vice versa) - you can plainly see that mixing them is fatal. Even mixing different data pointer types is sometimes troublesome, but there is usually a way to solve this problem. No, a generic function pointer needs some other syntax, something that makes it clear that any function type is allowed. At the same time, *one* more distinction needs to be made: between varargs and non-varargs functions. These cannot be mixed either (can you say: "opening an can of worms"? :-). ----- Shankar Unni E-Mail: Hewlett-Packard California Language Lab. Internet: shankar@hpda.hp.com Phone : (408) 447-5797 UUCP: ...!hplabs!hpda!shankar