Compatible Types
Overview
Two declarations with different types may still refer to the same object or function if they have compatible types. Two types are said to be nearly compatible if their unqualified types are compatible.
A composite type is constructed from two compatible types. It is the type that is compatible with both of the original types, including every available array size and every available parameter list from the original types.
Simple Types
Disregarding enumerations, two different simple types are never compatible. For two simple types to be (fully) compatible, they must use the same qualifiers and their unqualified base types must be the same.
Enumerations
Two enumerations found in different TUs are compatible if declared with the same tag (or lack thereof) and if there exists a bijection between their members such that each pair has the same name, same value, and compatible types.
Starting in C23, compatibility rules are extended to allow tagged enums declared in the same TU to be compatible. Furthermore, redeclaration of the same tagged enum is allowed.
Derived Types
Arrays
Array types are compatible if the element types are compatible and the sizes (when specified) match.
The composite type of two array types are determined by the following rules:
- If one type is an array of known constant size, the composite type is an array of that size.
- Otherwise, if one type is a VLA whose size is specified by an expression that isn't evaluated, the behavior is undefined.
- Otherwise, if one type is a VLA whose size is specified, the composite type is a VLA of that size.
- Otherwise, if one type is a VLA of unspecified size, the composite type is a VLA of unspecified size.
- Otherwise, both types are arrays of unknown size and the composite type is an array of unknown size.
Structures
Two structures found in different TUs are compatible if declared with the same tag (or lack thereof) and if there exists a bijection between their members such that each pair has the same name and compatible types. Members must be declared in the same order.
Starting in C23, compatibility rules are extended to allow tagged structs declared in the same TU to be compatible. Furthermore, redeclaration of the same tagged struct is allowed.
Unions
Two unions found in different TUs are compatible if declared with the same tag (or lack thereof) and if there exists a bijection between their members such that each pair has the same name and compatible types.
Starting in C23, compatibility rules are extended to allow tagged unions declared in the same TU to be compatible. Such unions must have members defined in the same order. Furthermore, redeclaration of the same tagged union in a TU is allowed.
Pointers
Two pointers are compatible if their target types are compatible and they have the same type qualifiers.
If two pointer types are nearly compatible, and the first type has all the qualifiers of the second type, we say the first is upward compatible with the second. Only two forms of implicit conversions are permitted for data pointers:
- Assignments to and from
void*, and - Assignments where the assigned pointer's target type is upward compatible with the right operand.
- That is, assignments add a qualifier to the target type.
Functions
Function types that specify argument types are compatible if the return types are compatible and the argument types are compatible, argument by argument. In addition, they must all agree in whether they use ... to allow additional arguments.
Prior to C23, function types that do not specify argument types are compatible if the return types are. Otherwise the argument types are compatible with function types that omit them, if the return types are compatible and the specified argument types are unaltered by argument promotions.
The composite type of two function types is determined as follows:
- If only one type is a function type with a parameter type list, the composite type is a function type with the parameter type list.
- If both types are function types with parameter type lists, the type of each parameter in the composite parameter type list is the composite type of the corresponding parameters.