Issue
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.
Solution
While it's allowed to assign a pointer to a non-const
type to a pointer to a const
type, that only applies to the first "level" of pointer. If this were allowed, it would be possible to allow a const
object to be modified.
For example:
const char c = 1;
const char *p1 = &c;
char *p2;
char **pp1 = &p2;
const char **pp2 = pp1; // invalid char ** to const char ** conversion
*pp2 = p1; // p2 now points to c (no warning!)
*p2 = 2; // modifying a const object (no warning!), UB
In the above case is slightly different from yours since only the "outer level" is const
. If pp2
were defined as const char * const *pp2
then 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 is const
qualified.
Applying a cast, as you've done, is the appropriate fix for this case.
Answered By - dbush Answer Checked By - David Goodson (WPSolving Volunteer)