Search code examples
cgccwarnings

const struct with pointer, discarded qualifier without warning


I have a structure with a pointer to something. I was expecting that accessing this pointer via a pointer-to-const-struct to the struct gives me a pointer-to-const-something. But gcc does not produce a warning in this case:

#include <stdlib.h>    
    
struct S {    
    void* ptr;    
};    
    
struct S* create(void)    
{    
    struct S* S = malloc(sizeof(*S));    
    S->ptr = malloc(sizeof(int));    
    return S;    
}    
    
void some_func(void* p);    
    
int main(void)    
{    
    struct S* S = create();    
    const void* ptr = S->ptr;    
    const struct S* SC = S;    
    some_func(ptr); // warning as expected    
    some_func(SC->ptr); // no warning    
} 

So is SC->ptr actually a const void*? I always assumed but now I'm confused. Is there a possibility to get a warning in this case?


Solution

  • SC->ptr is a void * const. It is not a const void * or const void * const.

    const struct S* SC = S; defines SC to be a pointer to a struct S that is const-qualified. The fact the structure is const-qualified means you should not modify the structure. The structure contains a member ptr of type void *. Because the structure is const-qualified, its members are const-qualified. That means you should not change ptr. Its type is void * const.

    However, that does not affect what ptr points to. Regardless of whether ptr itself is const-qualified, it points to void, not to const void.

    The C standard does not provide good means of working with multiple versions of a structure in which one version has members that point to non-const types and the other has members that point to const types. In general, there is no good way to convert one such structure into the other type.