Shahbaz
Shahbaz

Reputation: 47553

What is char * const *?

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

Answers (2)

Attila
Attila

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

Shahbaz
Shahbaz

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

Related Questions