Oracle® Solaris Studio 12.4:C 用户指南

退出打印视图

更新时间: 2014 年 12 月
 
 

5.4.4 示例:Struct 字段

考虑以下源代码示例。

struct foo {
        int f1;
        int f2;
} *fp;

struct bar {
        int b1;
        int b2;
} *bp;

struct cat {
        int c1;
        struct foo cf;
        int c2;
        int c3;
} *cp;

struct dog {
        int d1;
        int d2;
        struct bar db;
        int d3;
} *dp;

如果该示例是使用 -xalias_level=weak 选项编译的,编译器将假定以下别名信息:

  • fp->f1 可将 bp->b1cp->c1dp->d1cp->cf.f1df->db.b1 作为别名。

  • fp->f2 可将 bp->b2cp->cf.f1dp->d2cp->cf.f2df->db.b2cp->c2 作为别名。

  • bp->b1 可将 fp->f1cp->c1dp->d1cp->cf.f1df->db.b1 作为别名。

  • bp->b2 可将 fp->f2cp->cf.f1dp->d2cp->cf.f1df->db.b2 作为别名。

fp->f2 可将 cp->c2 作为别名,因为*dp 可将 *cp 作为别名,*fp 可将 dp->db 作为别名。

  • cp->c1 可将 fp->f1bp->b1dp->d1dp->db.b1 作为别名。

  • cp->cf.f1 可将 fp->f1fp->f2bp->b1bp->b2dp->d2dp->d1 作为别名。

cp->cf.f1 不将 dp->db.b1 作为别名。

  • cp->cf.f2 可将 fp->f2bp->b2dp->db.b1dp->d2 作为别名。

  • cp->c2 可将 dp->db.b2 作为别名。

cp->c2 不将 dp->db.b1 作为别名,cp->c2 不将 dp->d3 作为别名。

对于偏移,仅当 *dpcp->cf 作为别名时,cp->c2 才可将 db->db.b1 作为别名。但是,如果 *dpcp->cf 作为别名,则 dp->db.b1 必须在 foo cf 末尾之后设定别名,这是对象约束所禁止的。因此,编译器假定 cp->c2 不可将 db->db.b1 作为别名。

cp->c3 可将 dp->d3 作为别名。

请注意,cp->c3 不将 dp->db.b2 作为别名。由于具有非关联化所涉及的类型的字段的偏移不同并且不重叠,因此这些内存引用不设定别名。基于这种情况,编译器假定它们不能设定别名。

  • dp->d1 可将 fp->f1bp->b1cp->c1 作为别名。

  • dp->d2 可将 fp->f2bp->b2cp->cf.f1 作为别名。

  • dp->db.b1 可将 fp->f1bp->b1cp->c1 作为别名。

  • dp->db.b2 可将 fp->f2bp->b2cp->c2cp->cf.f1 作为别名。

  • dp->d3 可将 cp->c3 作为别名。

请注意,dp->d3 不将 cp->cf.f2 作为别名。由于具有非关联化所涉及的类型的字段的偏移不同并且不重叠,因此这些内存引用不设定别名。基于此分析,编译器假定它们不能设定别名。

如果该示例是使用 -xalias_level=layout 选项编译的,编译器只假定以下别名信息:

  • fp->f1bp->b1cp->c1dp->d1 都可以互为别名。

  • fp->f2bp->b2dp->d2 都可以互为别名。

  • fp->f1 可将 cp->cf.f1dp->db.b1 作为别名。

  • bp->b1 可将 cp->cf.f1dp->db.b1 作为别名。

  • fp->f2 可将 cp->cf.f2dp->db.b2 作为别名。

  • bp->b2 可将 cp->cf.f2dp->db.b2 作为别名。

如果该示例是使用 -xalias_level=strict 选项编译的,编译器只假定以下别名信息:

  • fp->f1bp->b1 可以互为别名。

  • fp->f2bp->b2 可以互为别名。

  • fp->f1 可将 cp->cf.f1dp->db.b1 作为别名。

  • bp->b1 可将 cp->cf.f1dp->db.b1 作为别名。

  • fp->f2 可将 cp->cf.f2dp->db.b2 作为别名。

  • bp->b2 可将 cp->cf.f2dp->db.b2 作为别名。

如果该示例是使用 -xalias_level=std 选项编译的,编译器只假定以下别名信息:

  • fp->f1 可将 cp->cf.f1 作为别名。

  • bp->b1 可将 dp->db.b1 作为别名。

  • fp->f2 可将 cp->cf.f2 作为别名。

  • bp->b2 可将 dp->db.b2 作为别名。