This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: 'char **' <-> 'unsigned char **' and aliasing/punning in C / GNU C


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]