From the man page of qsort, in an example of sorting strings:
static int
cmpstringp(const void *p1, const void *p2)
{
/* The actual arguments to this function are "pointers to
pointers to char", but strcmp(3) arguments are "pointers
to char", hence the following cast plus dereference */
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
Why is it necessary to have char * const * in the arguments to strcmp()? Isn’t char * enough?
const void* p1says that whateverp1points at is not changed by this function. If you didthat would be a setup to potentially break that promise, because you could then do
So a cast from
const void*tochar**is said to “cast away const”. Legal, but some compilers will warn if you use a cast to both cast away const and otherwise change the type at once.The cast that doesn’t break the promise of the
const void* p1declaration is the one used:Now
*p1_arg, the thingp1points to, can’t be changed just like we said. You could change the characters in it though:The function declaration never said anything about them, and you say you know them to originally be non-
const chars. So it’s allowable, even though the function doesn’t actually do any such thing.Then you dereference that (as an rvalue) to get a
char*. That can legally be passed as theconst char*argument tostrcmpby automaticconstpromotion.