Reputation: 47553
So it seems like it means a pointer to a constant pointer to char
. That is it points to a char * const
, so far so good.
What gets me confused is where and how I saw it used. I was looking at the man page for qsort
and the example does the following to convert the pointers to elements of a char **
(an array of strings), (pointers to elements seen as const void *
) to normal char pointers feedable to strcmp
:
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);
}
My question is, why is there a cast to char * const *
? Why isn't it just a const char **
(because eventually we want to send a const char *
to strcmp
)?
Upvotes: 0
Views: 3890
Reputation: 28762
When a function declares that it takes a pointer-to-const elements (e.g. strcmp()
) it means that the function promises not to mody the elements via the pointer, it does not mean that the parameters passed to that function must be pointers-to-const themselves.
Remember: the const
modifier is a contract term, basically meaning that the declaring function promises not to modify the element the const
modifies. Conversion in the direction of non-const -> const therefore is usually OK.
Upvotes: 5
Reputation: 47553
char * const *
indeed means a pointer to a constant pointer to chars. The reason this cast is performed in the code in the question is the following:
p1
and p2
are (non-const) pointers to a constant location. Let's assume the type of this location is const T
.
Now we want to cast p1
and p2
to their real types. We know that each element of the array is a char *
, therefore T = char *
. That is const T
is a constant pointer to char, which is written as char * const
.
Since p1
and p2
are pointers to the elements of the array, they are of type const T *
, which is char * const *
.
Since the function merely calls strcmp
, in truth it wouldn't have made any difference if the parameters were cast to char **
or const char **
or const char * const *
or whatever.
Upvotes: 6