Oracle® Solaris Studio 12.4: C User's Guide

Exit Print View

Updated: March 2015
 
 

5.4.3 Example: Interior Pointers

Consider the following example source code that demonstrates that certain levels of aliasing cannot handle interior pointers. For a definition of interior pointers see Table B–13.

struct foo {
        int f1;
        struct bar *f2;
        struct bar *f3;
        int f4;
        int f5;
        struct bar fb[10];
} *fp;

struct bar
        struct bar *b2;
        struct bar *b3;
        int b4;
} *bp;

bp=(struct bar*)(&fp->f2);

The dereference in this example is not supported by weak, layout, strict, or std. After the pointer assignment bp=(struct bar*)(&fp->f2), the following pair of memory accesses touches the same memory locations:

  • fp->f2 and bp->b2 access the same memory location

  • fp->f3 and bp->b3 access the same memory location

  • fp->f4 and bp->b4 access the same memory location

However, with the options weak, layout, strict, and std, the compiler assumes that fp->f2 and bp->b2 do not alias. The compiler makes this assumption because b2 has an offset of zero, which is different from the offset of f2 (four bytes), and foo and bar do not have a common initial sequence. Similarly, the compiler also assumes that bp->b3 does not alias fp->f3, and bp->b4 does not alias fp->f4.

Thus, the pointer assignment bp=(struct bar*)(&fp->f2)creates a situation in which the compiler’s assumptions about alias information are incorrect. This situation could lead to incorrect optimization.

Try compiling after you make the modifications shown in the following example.

struct foo {
        int f1;
        struct bar fb;   /* Modified line */
#define f2 fb.b2         /* Modified line */
#define f3 fb.b3         /* Modified line */
#define f4 fb.b4         /* Modified line */
        int f5;
        struct bar fb[10];
} *fp;

struct bar
        struct bar *b2;
        struct bar *b3;
        int b4;
} *bp;

bp=(struct bar*)(&fp->f2);

After the pointer assignment bp=(struct bar*)(&fp->f2), the following pair of memory accesses touches the same memory locations:

  • fp->f2 and bp->b2

  • fp->f3 and bp->b3

  • fp->f4 and bp->b4

The changes shown in this code example illustrate that the expression fp->f2 is another form of the expression fp->fb.b2. Because fp->fb is of type bar, fp->f2 accesses the b2 field of bar. Furthermore, bp->b2 also accesses the b2 field of bar. Therefore, the compiler assumes that fp->f2 aliases bp->b2. Similarly, the compiler assumes that fp->f3 aliases bp->b3, and fp->f4 aliases bp->b4. As a result, the aliasing assumed by the compiler matches the actual aliases caused by the pointer assignment.