Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!clyde.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!apple!usc!cs.utexas.edu!tut.cis.ohio-state.edu!att!cbnewsl!cbnewsk!pegasus!hansen From: hansen@pegasus.att.com (Tony L. Hansen) Newsgroups: comp.lang.c++ Subject: Re: Comparison functions for qsort() and bsearch() Summary: qsort and MI Keywords: Sun, C++ Message-ID: <1991Jan6.050801.20821@cbnewsk.att.com> Date: 6 Jan 91 05:08:01 GMT References: <3069@lupine.NCD.COM> <277640DD.4A70@tct.uucp> <1990Dec26.160636.15566@clear.com> Sender: hansen@cbnewsk.att.com (tony.l.hansen) Organization: AT&T Bell Laboratories Lines: 49 << From: chip@tct.uucp (Chip Salzenberg) << Both qsort() and bsearch() require a pointer to a function which does << *actually* take two parameters of type pointer-to-void. The fact that << the function in question will almost immediately cast those pointers << into pointer-to-T is utterly irrelevant. < From: rmartin@clear.com (Bob Martin) < I dissagree. As Ron said in his article. It is always possible to < cast a pointer to anything to a pointer to void. But it is not < guaranteed that you can cast a pointer to void back to its original. < Case in point is a class derived from multiple bases: < class AB : public A, public B; < Now take the following variable: < AB *ab; < The following two casts work just fine: < (A *)ab; (B *)ab; < But the following, though it may compile, is likely not to work < properly because it miscalculates the address of at least one of the < base classes. < (A *)(void *)ab; or (B *)(void *)ab; < Yet if qsort is to sort objects of type AB, then this is precicely what < the void* implementation of compar would be asked to do! Worse yet the < compiler can't catch this error and will thus allow corrupted pointers < loose in your program. Amost certainly the program will crash. Bob, you're seriously mixing apples and oranges, and getting caught in the middle. You're right, you cannot take a void* created from an AB* and cast it directly to a B* and expect things to work out right. SO DON'T DO IT! No comparison function passed to qsort() should ever do that! You're passing an AB* cast to a void*, so cast the void* back to an AB*! If you choose to go on from there to an A* or a B*, fine. But don't go directly from the void* to an A* or B*. In other words, declare your comparison function like this: int comparison(const void *a, const void *b) { const AB *ABa = (const AB*)a; const AB *ABb = (const AB*)b; // compare *ABa with *ABb } If you do so, everything works out just fine. See another article of mine on a brief description of a template definition of qsort(). Tony Hansen att!pegasus!hansen, attmail!tony hansen@pegasus.att.com tony@attmail.com