I have the following code:
typedef struct S1 S1_t;
struct S1
{
uint8_t *ptr1;
uint8_t **ptr2;
};
void get_ptr1(const S1_t *s1, uint8_t const **ptr1)
{
*ptr1= s1->ptr1;
}
void get_ptr2(const S1_t *s1, uint8_t const *const **ptr2)
{
*ptr2 = s1->ptr2;
}
If I leave it like that, I get the following warning from the GCC compiler for the function get_ptr2:
assignment to ‘const uint8_t * const*’ {aka ‘const unsigned char * const*’} from incompatible pointer type ‘uint8_t **’ {aka ‘unsigned char **’}
In order for me to mute the warning, I have to cast s1->ptr2 before assigning it to ptr2:
void get_ptr2(const S1_t *s1, uint8_t const *const **ptr2)
{
*ptr2 = (const uint8_t *const *)s1->ptr2;
return 0;
}
I don't understand why I need to do this cast operation here, when I don't need to do a (const uint8_t *) cast in get_ptr1?
My goal here is to implement getter functions for the structure S1's members, and I want to make sure the function getting those members cannot modify them. Is the compiler throwing a warning at me because I am doing something dangerous here?
I have the -wall and -wextra compilation option flag enabled.
While it's allowed to assign a pointer to a non-
consttype to a pointer to aconsttype, that only applies to the first "level" of pointer. If this were allowed, it would be possible to allow aconstobject to be modified.For example:
In the above case is slightly different from yours since only the "outer level" is
const. Ifpp2were defined asconst char * const *pp2then this wouldn't be possible, as the line*pp2 = p1;would contain an error. This is really a defect in the C standard that your case isn't allowed, given that each pointer level in the destination type isconstqualified.Applying a cast, as you've done, is the appropriate fix for this case.