(SPARC) 指定了以下命令时,C++ 编译器可以执行基于类型的别名分析和优化:
-xalias_level[=n ]
其中 n 是 any、simple 或 compatible。
-xalias_level=any
在此分析级别上,编译器假定任何类型都可以为其他类型起别名。不过尽管只是假定,但还是可以执行某些优化。
-xalias_level=simple
编译器假定简单的类型没有别名。具体来说就是具有动态类型的存储对象,这些类型是以下简单类型之一:
char |
short int |
long int |
float |
signed char |
unsigned short int |
unsigned long int |
double |
unsigned char |
int |
long long int |
long double |
wchar_t |
unsigned int |
unsigned long long int |
枚举类型 |
数据指针类型 |
函数指针类型 |
数据成员指针类型 |
函数成员指针类型 |
只能通过以下类型的左值访问:
对象的动态类型
动态类型对象的 constant 或 volatile 限定版本,与动态类型对象对应的带符号或无符号类型
与动态类型对象的 constant 或 volatile 限定版本对应的带符号或无符号类型
在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型
char 或 unsigned char 类型
-xalias_level=compatible
编译器假定布局不兼容类型没有别名。存储对象只能通过以下类型的左值访问:
对象的动态类型
对象动态类型的 constant 或 volatile 限定版本,与对象动态类型相对应的带符号或不带符号的类型
与动态类型对象的 constant 或 volatile 限定版本对应的带符号或无符号类型
在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型
动态类型对象的(可能是 constant 或 volatile 限定)基类类型
char 或 unsigned char type。
编译器假定所有引用的类型都与相应存储对象的动态类型是布局兼容的。两种类型在以下情况下是布局兼容的:
如果两个类型相同,则这两个类型就是布局兼容的类型。
如果两个类型仅在 constant 或 volatile 限定中不同,则这两个函数是布局兼容的类型。
每个存在的带符号整型对应(但是不相同)一个无符号整型。这些对应的类型是布局兼容的。
如果两个枚举类型具有相同的基础类型,则它们是布局兼容的。
如果两个简单旧数据 (Plain Old Data,POD) 结构类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个结构类型是布局兼容的。
如果两个 POD 联合类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个联合类型是布局兼容的。
在某些情况下具有存储对象动态类型的引用可能是非布局兼容的:
如果 POD 联合包含了两个或两个以上共享通用初始序列的 POD 结构,且 POD 联合对象当前包含了其中一个 POD 结构,就可以检查任何 POD 结构的通用初始部分。对包含一个或多个初始成员的序列来说,如果相应成员具有布局兼容类型(适用于位字段)和相同宽度,则两个 POD 结构共享一个通用初始序列。
指向 POD 结构对象的指针(使用 reinterpret_cast 适当转换)将指向该结构的初始成员,而如果该成员是位字段则指向该结构所在的单元。
如果未指定 -xalias_level,则编译器将该选项设置为 -xalias_level=any。如果指定了 -xalias_level 但未提供值,则编译器将该选项设置为 -xalias_level=compatible。
编译器在 -xO2 和更低的优化级别不执行基于类型的别名分析。
如果要使用 reinterpret_cast 或等价的旧式强制类型转换,程序可能会违反分析假定。此外,联合类型也违反了分析的假定,如以下示例所示。
union bitbucket{ int i; float f; }; int bitsof(float f){ bitbucket var; var.f=3.6; return var.i; } |