ISO/IEC 9899:2011 条款6.2.7——兼容类型与组合类型
6.2.7 兼容类型与组合类型
1、两个类型具有兼容类型,如果它们的类型是相同的。用于判定两个类型是否兼容的其它规则在6.7.2关于类型说明符中,6.7.3关于类型说明符中,6.7.6关于声明符中描述。[注:两个类型不需要完全相同而为兼容。]此外,声明在独立翻译单元中的两个结构体、联合体、枚举类型是兼容的,如果它们的标签以及成员满足以下要求:如果这两个类型在它们相应翻译单元中都是完整的,那么要应用以下额外的要求:在它们的成员之间应该要有一个一一对应关系,以至于相应成员的每一对以相兼容的类型来声明;如果成员对的其中一个成员用一个对齐说明符来声明,那么另一个要用等价的对齐说明符来声明;并且如果声明对的其中一个成员用一个名字声明,那么另一个要用相同的名字来声明。对于两个结构体,相应的成员应该以相同的次序来声明。对于两个结构体或联合体,相应的位域应该具有相同的宽度。对于两个枚举,相应的成员应该具有相同的值。
2、引用同一个对象或函数的所有声明应该具有相兼容的类型;否则,行为是未定义的。
3、一个组合类型可以从两个相互兼容的类型来构建;组合类型是与两个类型都兼容并且满足以下条件的类型:
——如果两个类型都是数组类型,那么要应用以下规则:
• 如果一个类型是一个已知常量大小的数组,那么组合类型是那个大小的一个数组。
• 否则,如果一个类型是一个变长数组,其大小通过一个尚未被计算的表达式指定,那么行为是未定义的。
• 否则,如果一个类型是一个变长数组,其大小已被指定,那么组合类型是那个大小的一个变长数组。
• 否则,如果一个类型是一个变长数组,其大小未指定,那么组合类型是一个未指定大小的变长数组。
• 否则,两个类型都是未知大小的两个数组,并且组合类型是一个未知大小的数组。
组合类型的元素类型是两个元素的组合类型。
如果仅有一个类型是带有一个形参类型列表的函数类型(一个函数原型),那么该组合类型是带有形参类型列表的函数原型。
——如果两个类型都是带有形参类型列表的函数类型,那么在组合形参类型中的每个形参的类型是相应形参的组合类型。
这些规则递归地运用于从两个类型派生出来的类型。
4、对于声明在一个作用域中的带有内部或外部连接的一个标识符,在此作用域中该标识符的声明是可见的[注:见6.2.1中所指定的,后续的声明可能隐藏先前的声明],如果先前的声明指定了内部或外部连接,那么在后续声明上的该标识符的类型变为组合类型。
5、例子:给定以下两个文件作用域的声明:
int f(int (*)(), double (*)[3]); int f(int (*)(char*), double (*)[]);
该函数的结果组合类型为:
int f(int (*)(char*), double (*)[3]);