[comp.lang.c] Casting Function Pointers

martin@mwtech.UUCP (Martin Weitzel) (05/23/91)

There has recently been some discussion about the correct way to
write comparison functions for qsort. (I've seen it as well in the
CUJ as also in a local German group). There seems to be some
consensus that the comparison function must be written expecting
two pointers to void and eventually casting (or assigning) them
internally to the required pointer type.

Taking into consideration that the number and types of function
parameters for any function determines the calling sequence and
further considering that qsort already makes a call to the comparison
function (via the function pointer) and hence has a certain calling
sequence compiled in, this all seems reasonable to me. (By "calling
sequence" I mean the details how parameters are transferred to the
function from the place where the function is called and how the
parameters are accessed from inside the function. Of course, both
ways must match.)

But have a look at the example in K&R-II, page 119-120 and the
explanations that accompany it - isn't it, say, at least a bit
misleading, or, may be, even wrong? (Oh boy, was this hard to type
in now, suspecting the fathers of C to have written something that
might be wrong.)

The point in question is the cast of the comparison function pointer
when handed as parameter to qsort and the explanation for the cast:

	"The elaborate cast of the function argument casts the
	arguments of the comparison function. These will generally
	have no effect on actual representation but assure the
	compiler that all is well."

First, IMHO the cast they apply has not the least effect on the
ARGUMENTS of the COMPARISION function;

Second, IMHO ANSI C even GUARANTEES that the cast has no effect
on the REPRESENTATION, since all function pointers have the same
representation and pointers to char have the same representation
as pointers to void. (This second point would really be of minor
importance - basically it centers on whether one could omit
"generally" from the last sentence above. As this sentence could
be seen to refer also to the sentence immediately before the one
with which I started my citation, one could even argue that the
"generally" justified. But I mention it because I think it points
the naive reader into quite a wrong direction.)

Third and most important: Will the guarantees ANSI C gives with
respect to the (identical) representation of certain pointer types
extend to the calling sequence of a function? Or, in the context
of the above example: Does the identical representation of pointers
to char and pointers to void extend to an identical calling sequence
for |int f1(void *, void *)| and |int f2(char *, char *)| ? If not,
the example in K&R-II is not guaranteed to work!
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83