In C, const char *p
is sometimes called a "read-only" pointer: a pointer to a constant object (in this case, a char
).
It would seem that either
const char **p
const char *const *p
would be the equivalent declarations for a read-only pointer to a pointer, depending on how many levels of indirection are immutable.
However, compilers (gcc, clang) generate a warning.
My Questions: How do you pass a pointer to a pointer (like char **p
) to a function as a "read-only" pointer without generating a warning? If an explicit cast is required, why in the case of char **p
and not char *p
?
More Details
Here is a concrete example of what I'm trying to achieve.
Read-only Pointer
This code treats char *ptr
as a read-only pointer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void readonly(const char *ptr)
{
// ... do something with ptr ...
// but modifying the object it points to is forbidden
// *ptr = 'j'; // error: read-only variable is not assignable
}
int main(void)
{
char *ptr = malloc(12*sizeof(char));
strcpy(ptr, "hello world");
printf("before: %s\n", ptr);
readonly(ptr);
printf("after: %s\n", ptr);
free(ptr);
return 0;
}
The qualifier const
is added in the function call without any complaints.
Read-only Pointer to Pointer
I would expect that a similar function call should be possible with a pointer to a pointer.
void readonly(const char *const *ptr)
{
// ... do something with ptr ...
// but modifying the object it points to is forbidden
// **ptr = 'j';
}
int main(void)
{
char **ptr;
ptr = (char **) malloc(2*sizeof(char *));
ptr[0] = malloc(14*sizeof(char));
strcpy(ptr[0], "hello world 0");
ptr[1] = malloc(14*sizeof(char));
strcpy(ptr[1], "hello world 1");
printf("before: %s %s\n", ptr[0], ptr[1]);
readonly(ptr);
printf("after: %s %s\n", ptr[0], ptr[1]);
free(ptr[1]);
free(ptr[0]);
free(ptr);
return 0;
}
The clang compiler (version 6.0.0) gives the most human-readable warning.
warning: passing 'char **' to parameter of type
'const char *const *' discards qualifiers in nested pointer types
[-Wincompatible-pointer-types-discards-qualifiers]
readonly(ptr);
^~~
note: passing argument to parameter 'ptr' here
void readonly(const char *const *ptr)
But gcc (8.1.1) also gives a warning.
Aside: It seems strange that clang says that passing char **
discards the qualifier, when I'm trying to add the qualifier?
The Questions
How do you pass a pointer to a pointer (like
char **p
) to a function as a "read-only" pointer without generating a warning?If an explicit cast is required, why in the case of
char **p
and notchar *p
?