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:

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:

  1. Assignments to and from void*, and
  2. 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:

Powered by Forestry.md