a pointer aliasing problem gcc won't tell you about

this was suggested to me after I sent in a patch for glibc to remove some warings.

consider this code

#include <stdio.h>
 
int i = 200;
int j = 100;
void *ptr2j = &j;
 
int **fn(void) {
        void **ptr =  &ptr2j;
        *ptr = &i;
        return ((int **)ptr);
}
 
int main(void) {
        int *i = *( fn() );
        printf("j now %d\n",*i);
        return 0;
}

compiling with  gcc -Wall -fstrict-aliasing   gives no warnings, but the code is incorrect. We are declaring void **ptr in int **fn(void), and our return value is int **, so we cast from void ** back. But main dereferences the return and naturally assumes it is of type int *. But it's not -- we declared it as void * above.

This means you are accessing the same word of memory from a pointer of two different types; this breaks type based aliasing rules and means that gcc may produce incorrect code.

Now doing what you think is correct gives you a warning. consider

#include <stdio.h>

int i = 200;                
int j = 100;
void *ptr2j = &j;
                                                                                                                                        
int **fn(void) {
        int **ptr =  (int **)(&ptr2j);
        *ptr = &i;
        return (ptr);
}
                                                                                                                                        
int main(void) {
        int *i = *( fn() );
        printf("j now %d\n",*i);
        return 0;
}

gives

ianw@tartufi:~$ gcc-snap -Wall -fstrict-aliasing -o test test.c
test.c: In function `fn':
test.c:8: warning: dereferencing type-punned pointer will break strict-aliasing rules

gcc is now seeing the problem we hid from it -- it knows that if we dereference ptr it will be pointing to void, but it's declared as a int **.

How to get around it

Maybe a union?

It has been pointed out that, although this might remove the warning, it is not correct as you still have the same problem.

IA64wiki: pointeraliasing (last edited 2009-12-10 03:14:01 by localhost)

Gelato@UNSW is sponsored by
the University of New South Wales National ICT Australia The Gelato Federation Hewlett-Packard Company Australian Research Council
Please contact us with any questions or comments.