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 **pand not- char *p?
 
     
     
     
    