ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <87************@benpfaff.org>,
Ben Pfaff <bl*@cs.stanford.eduwrote:
>>ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
>>[call to qsort]
>>In order to fix the problem, you need to cast blbp_CtnRecCompare
to the correct type as you pass it in.
>>No. The OP needs to declare blbp_CtnRecCompare to be of the
correct type. Then the cast is unnecessary.
>>If the cast is necessary, then the call to qsort is wrong.
K&R2 section 5.11 "Pointers to Functions", page 119
[...]
void qsort(void *lineptr[], int left, int right,
int (*comp)(void *, void *));
int numcmp(char *, char *);
[...]
qsort((void **) lineptr, 0, nlines-1,
(int (*)(void*,void*))(numeric ? numcmp : strcmp));
[...]
Did something relevant change between the publication of K&R2 and
the C89 standard such that K&R2 became incorrect ?
This part of K&R2 is badly written, as admitted on the official
errata page at:
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html
The relevant text is:
119-121(5.11): The qsort discussion needs recasting in
several ways. First, qsort is a standard routine in ANSI/ISO
C, so the rendition here should be given a different name,
especially because the arguments to standard qsort are a bit
different: the standard accepts a base pointer and a count,
while this example uses a base pointer and two offsets.
Also, the comparison-routine argument is not treated
well. The call shown on p 119, with an argument
(int (*)(void*,void*))(numeric? numcmp : strcmp)
is not only complicated, but only barely passes muster. Both
numcmp and strcmp take char * arguments, but this expression
casts pointers to these functions to a function pointer that
takes void * arguments. The standard does say that void * and
char * have the same representation, so the example will
almost certainly work in practice, and is at least defensible
under the standard. There are too many lessons in these
pages.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}