This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: 'char **' <-> 'unsigned char **' and aliasing/punning in C / GNU C
- From: Ian Lance Taylor <iant at google dot com>
- To: Pedro Alves <palves at redhat dot com>
- Cc: GCC Patches <gcc-help at gcc dot gnu dot org>
- Date: Fri, 8 Mar 2013 11:36:25 -0800
- Subject: Re: 'char **' <-> 'unsigned char **' and aliasing/punning in C / GNU C
- References: <513A3AEB.10704@redhat.com>
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