兼容类型
ISO/IEC 9899:2018标准第6.2.7 Compatible type and composite type节规定:所有引用相同对象或者函数的声明都应具有兼容类型;否则其行为是未定义的。相同类型一定是兼容类型;但兼容类型不一定是相同类型。本文就基本类型,结构、联合、枚举类型,指针类型,数组类型,函数类型等类型讨论一下C语言中的类型兼容问题。
一、基本类型的兼容性
根据ISO/IEC 9899:2018标准第6.2.5 Types节,C语言中的基本类型(basic types)及相互关系如下图所示:
注:枚举类型虽属于整数类型,但标准并未将其划入基本类型。
如果两个类型是相同类型,那么这两个类型是兼容的。
int a = 0; int b = 0;
变量a、b的类型是相同的,所以变量a、b的类型也是兼容的。
根据ISO/IEC 9899:2018标准第6.7.2 Type specifiers节,下面相同行中逗号分隔的类型说明符集表示相同的类型。
- short, signed short, short int, signed short int
- unsigned short, unsigned short int
- int, signed, signed int
- unsigned, unsigned int
- long, signed long, long int, signed long int
- unsigned long, unsigned long int
- long long, signed long long, long long int, signed long long int
- unsigned long long, unsigned long long int
short a = 0; signed short b = 0; short int c = 0; signed short int d = 0;
变量a、b、c、d的类型是相同的,所以变量a、b、c、d的类型也是兼容的。
通过typedef引入的别名如果与对应的内置类型(built-in types)是相同的类型,它们之间也是兼容的。
typedef unsigned Money; Money income = 0; unsigned expenditure = 0;
这里Money、unsigned是相同的类型,所以它们也是兼容类型。
上述类型都是非限定类型(unqualified type);如果存在类型限定符(type qualifier),则类型是限定类型(qualified type)。每个非限定类型都存在多个对应的限定类型。非限定类型及其对应的限定类型之间的关系是属于相同类型类别且具有相同表示形式和对齐要求的不同类型;作为函数参数、函数返回值、联合成员时,它们之间可以互换。如果存在类型限定符,兼容类型的类型限定符应该是相同的,并且其对应的非限定类型也应该是兼容的。
注:C语言中类型限定符包括const、restrict、volatile、_Atomic。
typedef unsigned Money; const Money income = 0; volatile unsigned expenditure = 0; const unsigned profit = 0;
const Money与const unsigned是兼容的,但它们与volatile unsigned是不兼容的。
如果存在多个类型限定符,类型限定符的先后顺序不影响类型的兼容性。
const volatile int a = 0; volatile const int b = 0;
变量a、b的类型是兼容类型。