Oracle® Solaris Studio 12.4:C 用户指南

退出打印视图

更新时间: 2014 年 12 月
 
 

5.4.3 示例:内部指针

考虑下列源代码示例,它说明某些别名级别无法处理内部指针。有关内部指针的定义,请参见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);

weaklayoutstrictstd 不支持该示例中的非关联化。在指针赋值 bp=(struct bar*)(&fp->f2) 之后,以下各对内存访问会访问相同的内存位置:

  • fp->f2bp->b2 会访问相同内存位置

  • fp->f3bp->b3 会访问相同内存位置

  • fp->f4bp->b4 会访问相同内存位置

但是,在使用 weaklayoutstrictstd 选项时,编译器假定 fp->f2bp->b2 不互为别名。由于 b2 的偏移为零,与 f2 的偏移(四字节)不同,并且 foobar 没有公共初始序列,因此编译器作出该假定。同样,编译器也假定 bp->b3fp->f3 不互为别名,bp->b4fp->f4 不互为别名。

因此,指针赋值 bp=(struct bar*)(&fp->f2) 将使编译器关于别名信息的假定不正确。此情况可能会导致不正确的优化。

请在进行以下示例中显示的修改之后尝试编译。

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);

在指针赋值 bp=(struct bar*)(&fp->f2) 之后,以下各对内存访问会访问相同的内存位置:

  • fp->f2bp->b2

  • fp->f3bp->b3

  • fp->f4bp->b4

此代码示例中显示的更改说明了表达式 fp->f2 是表达式 fp->fb.b2 的另一种形式。由于 fp->fb 的类型为 bar,因此fp->f2 会访问 barb2 字段。此外,bp->b2 也会访问 barb2 字段。因此,编译器假定 fp->f2bp->b2 作为别名。同样,编译器也假定 fp->f3bp->b3 作为别名,fp->f4bp->b4 作为别名。结果,编译器假定的别名与指针赋值产生的实际别名匹配。