Path: utzoo!mnetor!uunet!husc6!bloom-beacon!gatech!uflorida!umd5!purdue!i.cc.purdue.edu!j.cc.purdue.edu!pur-ee!uiucdcs!uxc.cso.uiuc.edu!uicsrd.csrd.uiuc.edu!mcdaniel From: mcdaniel@uicsrd.csrd.uiuc.edu Newsgroups: comp.lang.c Subject: Bug in new K&R? Message-ID: <44200009@uicsrd.csrd.uiuc.edu> Date: 4 May 88 21:34:00 GMT Lines: 44 Nf-ID: #N:uicsrd.csrd.uiuc.edu:44200009:000:1622 Nf-From: uicsrd.csrd.uiuc.edu!mcdaniel May 4 16:34:00 1988 I just got the Second Edition of "The C Programming Language" by Kernighan & Richie. (The "New Testament"? :-) ) I'm puzzled by the example in section 5.11, "Pointers to Functions", pp. 119--120. It's a generic quicksort which sorts using an array of void pointers to the data. This "qsort" is passed a comparison function. void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void*)); "lineptr" is an array of lines to sort. "strcmp" is the normal string comparison function, and "numcmp" compares strings numerically (the results of atof() are compared): char *lineptr[MAXLINES]; int numcmp(char *, char *); The problem is that "qsort" is called thus: qsort((void **) lineptr, 0, nlines-1, (int (*)(void*,void*))(numeric ? numcmp : strcmp)); Are those two casts portable---is it guaranteed that "void *" and "char *" have the same internal representation? Is it likely that they would under any "reasonable" implementation (whatever THAT means)? Whether or not it's legal, the type punning above is obscene. I would use the following declarations: void *lineptr[MAXLINES]; int numcmp(void *, void *); int my_strcmp(void *, void *); If I'm careful to store them as "void *"s and use them as "char *"s, there are no storage or use type problems. -- Tim, the Bizarre and Oddly-Dressed Enchanter Center for Supercomputing Research and Development at the University of Illinois at Urbana-Champaign Internet, BITNET: mcdaniel@uicsrd.csrd.uiuc.edu UUCP: {ihnp4,uunet,convex}!uiucuxc!uicsrd!mcdaniel ARPANET: mcdaniel%uicsrd@uxc.cso.uiuc.edu CSNET: mcdaniel%uicsrd@uiuc.csnet