Oracle® Solaris Studio 12.4:C 用户指南

退出打印视图

更新时间: 2014 年 12 月
 
 

5.4.1 示例:别名级别

考虑以下代码。可以使用不同的别名级别对它进行编译,以说明显示类型的别名关系。

struct foo {
    int f1;
    short f2;
    short f3;
    int f4;
} *fp;

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

int *ip;
short *sp;

如果该示例是使用 -xalias_level=any 选项编译的,编译器将认为以下间接访问互为别名:

*ip*sp*fp*bpfp->f1fp->f2fp->f3fp->f4bp->b1bp->b2bp->b3

如果该示例是使用 -xalias_level=basic 选项编译的,编译器将认为以下间接访问互为别名:

*ip*bpfp->f1fp->f4bp->b1bp->b2bp->b3

另外,*spfp->f2fp->f3 可以互为别名,*sp*fp 可以互为别名。

但是,在 -xalias_level=basic 条件下,编译器作出以下假定:

  • *ip 不将 *sp 作为别名。

  • *ip 不将 fp->f2fp->f3 作为别名。

  • *sp 不将 fp->f1fp->f4bp->b1bp->b2bp->b3 作为别名。

由于两个间接访问的访问类型是不同的基本类型,因此编译器作出这些假定。

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

  • *ip 可将 *fpfp->f1fp->f4*bpbp->b1bp->b2bp->b3 作为别名。

  • *sp 可将 *fpfp->f2fp->f3 作为别名。

  • fp->f1 可将 bp->b1 作为别名。

  • fp->f4 可将 bp->b3 作为别名。

由于 f1 是结构中偏移为 0 的字段,而 b2 是结构中偏移为 4 个字节的字段,因此编译器假定 fp->fp1 不将 bp->b2 作为别名。同样,编译器假定 fp->f1 不将 bp->b3 作为别名,fp->f4 不将 bp->b1bp->b2 作为别名。

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

  • *ip 可将 *fp*bpfp->f1fp->f4bp->b1bp->b2bp->b3 作为别名。

  • *sp 可将 *fpfp->f2fp->f3 作为别名。

  • fp->f1 可将 bp->b1*bp 作为别名。

  • *fp*bp 可以互为别名。

fp->f4 不将 bp->b3 作为别名,因为 f4b3 不是 foobar 公共初始序列中的对应字段。

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

  • *ip 可将 *fpfp->f1fp->f4*bpbp->b1bp->b2bp->b3 作为别名。

  • *sp 可将 *fpfp->f2fp->f3 作为别名。

使用 -xalias_level=strict 时,编译器假定 *fp*bpfp->f1fp->f2fp->f3fp->f4bp->b1bp->b2bp->b3 不互为别名,因为在忽略字段名时 foobar 是不同的。但是,fp 可将 fp->f1 作为别名,bp 可将 bp->b1 作为别名。

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

  • *ip 可将 *fpfp->f1fp->f4*bpbp->b1bp->b2bp->b3 作为别名。

  • *sp 可将 *fpfp->f2fp->f3 作为别名。

但是,fp->f1 不将 bp->b1bp->b2bp->b3 作为别名,因为在考虑字段名时 foobar 是不同的。

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

  • *ip 不将 fp->f1fp->f4bp->b1bp->b2bp->b3 作为别名,因为 *ip 等指针不应指向结构内部。

  • 同样,*sp 不将 fp->f1fp->f3 作为别名。

  • 因为类型不同,*ip 不将 *fp*bp*sp 作为别名。

  • 因为类型不同,*sp 不将 *fp*bp*ip 作为别名。