考虑以下代码。可以使用不同的别名级别对它进行编译,以说明显示类型的别名关系。
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、*bp、fp->f1、fp->f2、fp->f3、fp->f4、bp->b1、bp->b2、bp->b3
如果该示例是使用 -xalias_level=basic 选项编译的,编译器将认为以下间接访问互为别名:
*ip、*bp、fp->f1、fp->f4、bp->b1、bp->b2、bp->b3
另外,*sp、fp->f2 和 fp->f3 可以互为别名,*sp 和 *fp 可以互为别名。
但是,在 -xalias_level=basic 条件下,编译器作出以下假定:
*ip 不将 *sp 作为别名。
*ip 不将 fp->f2 和 fp->f3 作为别名。
*sp 不将 fp->f1、fp->f4、bp->b1、bp->b2和 bp->b3 作为别名。
由于两个间接访问的访问类型是不同的基本类型,因此编译器作出这些假定。
如果该示例是使用 -xalias_level=weak 选项编译的,编译器将假定以下别名信息:
*ip 可将 *fp、fp->f1、fp->f4、*bp、bp->b1、bp->b2 和 bp->b3 作为别名。
*sp 可将 *fp、fp->f2 和 fp->f3 作为别名。
fp->f1 可将 bp->b1 作为别名。
fp->f4 可将 bp->b3 作为别名。
由于 f1 是结构中偏移为 0 的字段,而 b2 是结构中偏移为 4 个字节的字段,因此编译器假定 fp->fp1 不将 bp->b2 作为别名。同样,编译器假定 fp->f1 不将 bp->b3 作为别名,fp->f4 不将 bp->b1 或 bp->b2 作为别名。
如果该示例是使用 -xalias_level=layout 选项编译的,编译器将假定以下别名信息:
*ip 可将 *fp、*bp、fp->f1、fp->f4、bp->b1、bp->b2 和 bp->b3 作为别名。
*sp 可将 *fp、fp->f2 和 fp->f3 作为别名。
fp->f1 可将 bp->b1 和 *bp 作为别名。
*fp 和 *bp 可以互为别名。
fp->f4 不将 bp->b3 作为别名,因为 f4 和 b3 不是 foo 和 bar 公共初始序列中的对应字段。
如果该示例是使用 -xalias_level=strict 选项编译的,编译器将假定以下别名信息:
*ip 可将 *fp、fp->f1、fp->f4、*bp、bp->b1、bp->b2 和 bp->b3 作为别名。
*sp 可将 *fp、fp->f2 和 fp->f3 作为别名。
使用 -xalias_level=strict 时,编译器假定 *fp、*bp、fp->f1、fp->f2、fp->f3、fp->f4、bp->b1、bp->b2 和 bp->b3 不互为别名,因为在忽略字段名时 foo 和 bar 是不同的。但是,fp 可将 fp->f1 作为别名,bp 可将 bp->b1 作为别名。
如果该示例是使用 -xalias_level=std 选项编译的,编译器将假定以下别名信息:
*ip 可将 *fp、fp->f1、fp->f4、*bp、bp->b1、bp->b2 和 bp->b3 作为别名。
*sp 可将 *fp、fp->f2 和 fp->f3 作为别名。
但是,fp->f1 不将 bp->b1、bp->b2 或 bp->b3 作为别名,因为在考虑字段名时 foo 和 bar 是不同的。
如果该示例是使用 -xalias_level=strong 选项编译的,编译器将假定以下别名信息:
*ip 不将 fp->f1、fp->f4、bp->b1、bp->b2 和 bp->b3 作为别名,因为 *ip 等指针不应指向结构内部。
同样,*sp 不将 fp->f1 或 fp->f3 作为别名。
因为类型不同,*ip 不将 *fp、*bp 和 *sp 作为别名。
因为类型不同,*sp 不将 *fp、*bp 和 *ip 作为别名。