< c‎ | language

Objects, functions, and expressions have a property called type, which determines the interpretation of the binary value stored in an object or evaluated by the expression.


[edit] Type classification

The C type system consists of the following types:

  • the type void
  • basic types
  • the type char
  • signed integer types
  • standard: signed char, short, int, long, long long
  • extended: implementation defined, e.g. __int128
  • unsigned integer types
  • standard: _Bool, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long
  • extended: implementation-defined, e.g. __uint128
  • floating types
  • real floating types: float, double, long double
  • complex types: float _Complex, double _Complex, long double _Complex
  • imaginary types: float _Imaginary, double _Imaginary, long double _Imaginary
  • enumerated types
  • derived types
  • array types
  • structure types
  • union types
  • function types
  • pointer types
  • atomic types

For every type listed above several qualified versions of its type may exist, corresponding to the combinations of one, two, or all three of the const, volatile, and restrict qualifiers (where allowed by the qualifier's semantics)

[edit] Type groups

  • object types: all types that aren't function types
  • character types: char, signed char, unsigned char
  • integer types: char, signed integer types, unsigned integer types, enumerated types
  • real types: integer types and real floating types
  • arithmetic types: integer types and floating types
  • scalar types: arithmetic types and pointer types
  • aggregate types: array types and structure types
  • derived declarator types: array types, function types, and pointer types

[edit] Compatible types

In a C program, the declarations referring to the same object or function in different translation units do not have to use the same type. They only have to use sufficiently similar types, formally known as compatible types. Same applies to function calls and lvalue accesses; argument types must be compatible with parameter types and lvalue expression type must be compatible with the object type that is accessed.

The types T and U are compatible, if

  • they are the same type (same name or aliases introduced by a typedef)
  • they are identically cvr-qualified versions of compatible unqualified types
  • they are pointer types and are pointing to compatible types
  • they are array types, and
  • their element types are compatible, and
  • if both have constant size, that size is the same (Note: VLA is compatible with any array) (since C99)
  • they are both structure/union/enumeration types, and
  • (C99)if one is declared with a tag, the other must also be declared with the same tag.
  • if both are completed types, their members must correspond exactly in number, be declared with compatible types, and have matching names.
  • additionally, if they are enumerations, corresponding members must also have the same values.
  • additionally, if they are structures or unions,
  • Corresponding members must be declared in the same order (structures only)
  • Corresponding bit fields must have the same widths.
  • one is an enumerated type and the other is that enumeration's underlying type
  • they are function types, and
  • their return types are compatible
  • they both use parameter lists, the number of parameters (including the use of the ellipsis) is the same, the corresponding parameters have compatible types
  • one is an old-style (parameter-less) definition, the other has a parameter list, the parameter list does not use an ellipsis and each parameter is compatible (after function parameter type adjustment) with the corresponding old-style parameter after default argument promotions
  • one is an old-style (parameter-less) declaration, the other has a parameter list, the parameter list does not use an ellipsis, and all parameters (after function parameter type adjustment) are unaffected by default argument promotions

The type char is not compatible with signed char and not compatible with unsigned char.

If two declarations refer to the same object or function and do not use compatible types, the behavior of the program is undefined.

// Translation Unit 1
struct S {int a;};
extern struct S *x;  // compatible with TU2's x, but not with TU3's x
// Translation Unit 2
struct S;
extern struct S *x; // compatible with both x's
// Translation Unit 3
struct S {float a;};
extern struct S *x; // compatible with TU2's x, but not with TU1's x
// the behavior is undefined
// Translation Unit 1
#include <stdio.h>
struct s {int i;}; // compatible with TU3's s, but not TU2's
extern struct s x = {0}; // compatible with TU3's x
extern void f(void); // compatible with TU2's f
int main()
   return x.i;
// Translation Unit 2
struct s {float f;}; // compatible with TU4's s, but not TU1's s
extern struct s y = {3.14}; // compatible with TU4's y
void f() // compatible with TU1's f
// Translation Unit 3
struct s {int i;}; // compatible with TU1's s, but not TU2's s
extern struct s x; // compatible with TU1's x
// Translation Unit 4
struct s {float f;}; // compatible with TU2's s, but not TU1's s
extern struct s y; // compatible iwth TU2's y
// the behavior is well-defined: only multiple declarations
// of objects and functions must have compatible types, not the types themselves

Note: C++ has no concept of compatible types. A C program that declares two types that are compatible but not identical in different translation units is not a valid C++ program.

[edit] Composite types

[edit] Incomplete types

An incomplete type is an object type that lacks sufficient information to determine the size of the objects of that type. An incomplete type may be completed at some point in the translation unit

The following types are incomplete:

  • the type void. This type cannot be completed.
  • array type of unknown size. It can be completed by a later declaration that specifies the size.
  • structure or union type of unknown content. It can be completed by a declaration of the same structure or union that defines its content later in the same scope.

[edit] Type names

[edit] See also

C++ documentation for C++ Type