'char **' <-> 'unsigned char **' and aliasing/punning in C / GNU C
Ian Lance Taylor
iant@google.com
Fri Mar 8 19:36:00 GMT 2013
On 3/8/13, Pedro Alves <palves@redhat.com> wrote:
> I'm wondering if the following is valid C, and/or valid GNU C.
> Something like:
>
> /* Returns a new malloced buffer in *OUTP. */
> void target_read_memory (unsigned long addr, int len,
> unsigned char **outp);
>
> void bar ()
> {
> char *str;
>
> ...
> target_read_memory (addr, len, (unsigned char **) &str);
> ^^^^^^^^^^^^^^^^^^^^^^^
>
> // follows uses of str as a C string
> strlen (str); sscanf (str, ...);
> }
>
> chars are involved, but the cast is from a pointer to pointer,
> to another pointer to pointer, so I end up confused whether
> the char-aliases-everything rule kicks in around "str".
>
> gcc doesn't complain even with -fstrict-aliasing -O3, and I can imagine
> that if this didn't work, the world would break, but, from a language
> perspective, is that actually valid? If not, does gcc support this
> as a GNU C extension?
This question would be more appropriate on gcc-help than on gcc-patches.
I'm not sure, but I think you are asking whether a valid C program can
cast from char ** to unsigned char **, store a value into the unsigned
char **, and then use that value as a char*. The answer to that
question is yes, because qualifiers are ignored when considering
aliasing. That is, it is safe to cast from T* to unsigned T*.
The fact that char * aliases any other pointer does not arise here,
which is good because the cast from char ** to unsigned char ** does
not involve a char * pointer on either side.
Ian
More information about the Gcc-help
mailing list