考虑以下源代码示例。当使用不同的别名级别编译时,它说明显示的类型的别名关系。
struct foo { int f1; int f2; int f3; } *fp; struct bar { int b1; int b2; int b3; } *bp;
如果该示例是使用 -xalias_level=any 选项编译的,编译器将假定以下别名信息:
*fp、*bp、fp->f1、fp->f2、fp->f3、bp->b1、bp->b2 和 bp->b3 都可以互为别名,因为任何两个内存访问在 -xalias_level=any 级别上可互为别名。
如果该示例是使用 -xalias_level=basic 选项编译的,编译器将假定以下别名信息:
*fp、*bp、fp->f1、fp->f2、fp->f3、bp->b1、bp->b2 和 bp->b3 都可以互为别名。在本示例中,由于所有结构字段均为同一基本类型,因此任何两个使用指针 *fp 和 *bp 的字段访问都可以互为别名。
如果该示例是使用 -xalias_level=weak 选项编译的,编译器将假定以下别名信息:
*fp 和 *fp 可以互为别名。
fp->f1 可将 bp->b1、*bp 和 *fp 作为别名。
fp->f2 可将 bp->b2、*bp 和 *fp 作为别名。
fp->f3 可将 bp->b3、*bp 和 *fp 作为别名。
但是,-xalias_level=weak 强加以下限制:
由于 f1 的偏移为零,与 b2 的偏移(四字节)和 b3 的偏移(八字节)不同,因此 fp->f1 不将 bp->b2 或 bp->b3 作为别名。
由于 f2 的偏移为四字节,与 b1 的偏移(零字节)和 b3 的偏移(八字节)不同,因此 fp->f2 不将 bp->b1 或 bp->b3 作为别名。
由于 f3 的偏移为八字节,与 b1 的偏移(零字节)和 b2 的偏移(四字节)不同,因此 fp->f3 不将 bp->b1 或 bp->b2 作为别名。
如果该示例是使用 -xalias_level=layout 选项编译的,编译器将假定以下别名信息:
*fp 和 *bp 可以互为别名。
fp->f1 可将 bp->b1、*bp 和 *fp 作为别名。
fp->f2 可将 bp->b2、*bp 和 *fp 作为别名。
fp->f3 可将 bp->b3、*bp 和 *fp 作为别名。
但是,-xalias_level=layout 强加以下限制:
由于在 foo 和 bar 的公共初始序列中字段 f1 对应于字段 b1,因此 fp->f1 不将 bp->b2 或 bp->b3 作为别名。
由于在 foo 和 bar 的公共初始序列中字段 f2 对应于字段 b2,因此 fp->f2 不将 bp->b1 或 bp->b3 作为别名。
由于在 foo 和 bar 的公共初始序列中字段 f3 对应于字段 b3,因此 fp->f3 不将 bp->b1 或 bp->b2 作为别名。
如果该示例是使用 -xalias_level=strict 选项编译的,编译器将假定以下别名信息:
*fp 和 *bp 可以互为别名。
fp->f1 可将 bp->b1、*bp 和 *fp 作为别名。
fp->f2 可将 bp->b2、*bp 和 *fp 作为别名。
fp->f3 可将 bp->b3、*bp 和 *fp 作为别名。
但是,-xalias_level=strict 强加以下限制:
由于在 foo 和 bar 的公共初始序列中字段 f1 对应于字段 b1,因此 fp->f1 不将 bp->b2 或 bp->b3 作为别名。
由于在 foo 和 bar 的公共初始序列中字段 f2 对应于字段 b2,因此 fp->f2 不将 bp->b1 或 bp->b3 作为别名。
由于在 foo 和 bar 的公共初始序列中字段 f3 对应于字段 b3,因此 fp->f3 不将 bp->b1 或 bp->b2 作为别名。
如果该示例是使用 -xalias_level=std 选项编译的,编译器将假定以下别名信息:
fp->f1、fp->f2、fp->f3、bp->b1、bp->b2 和 bp->b3 不互为别名。
如果该示例是使用 -xalias_level=strong 选项编译的,编译器将假定以下别名信息:
fp->f1、fp->f2、fp->f3、bp->b1、bp->b2 和 bp->b3 不互为别名。