Types

Overview

Types in C are categorized corresponding to a hierarchy with a foundation comprising of the simple types. These types are then grouped and further categorized until we reach the top of the hierarchy consisting of all types.

All types are categorized as function types or object types. An object type is complete if there is sufficient information to determine the size of objects of that type. Otherwise we say it is incomplete.

The basic types comprise of char, the signed/unsigned integer types, and the floating point types. All basic types are complete object types.

The integer types comprise of char, the signed/unsigned integer types, and enums.

The arithmetic types comprise of the integer and floating point types. Each arithmetic type belongs to one type domain: the real type domain contains the real types and the complex type domain contains the complex types.

Literals

Since C23, number literals can use an apostrophe (') as a digit separator. For example, 10000 can instead be written as 10'000.

Integers

Negative integer literals are typed in a counterintuitive way. When the compiler sees a number of form -X, the type of X is determined before being negated. Promotion follows the first fit rule described as follows:

Decimal Binary, Octal, and Hexadecimal
int int
long unsigned
long long long
- unsigned long
- long long
- unsigned long long

Integer constants can be made a certain signedness or type by using the following suffixes. Note these supply a lower bound on the rank of the resulting type.

Suffix Type (At Least)
U unsigned
L long
LL long long
ULL unsigned long long

Floating-Point

Floating-point constants can be made a certain type by using the following suffixes.

Suffix Type (At Least)
F float
L long double

Compound Literals

A compound literal is an object of form (T){ INIT }. That is, a type in parentheses followed by an initializer in curly braces.

Since C23, a compound literal can include storage classes in their types. Compound literals have the same lifetime as a variable that would be declared with the same storage class within the same context.

The only possible exception are those that are const-qualified without any storage class specification in block scope. Such compound literals may not correspond to a unique object and can refer to storage available to the whole program execution.

Integer Constant Expressions

An integer constant expression (ICE) is a compile-time integer value. Its value must be determinable at compile time (e.g. no function calls are permitted). The only objects that may be evaluated are those defined as constexpr.

Size

The sizeof operator returns the size in bytes of its operand. The return type is size_t, an unsigned integer type, defined in <stddef.h>. For specific types, the sizeof operator has the following semantics:

The operand is only evaluated in the case of a VLA.

Alignment

For a large class of modern ISAs, storage for basic C datatypes respect self-alignment. This means chars can start on any byte address, shorts on any even address, 4-byte ints and floats must start on an address divisible by 4, and doubles must start on an address divisible by 8. Likewise pointers are also self-aligned.

The alignof (_Alignof) operator yields the alignment requirement of its operand type. The return type is also size_t. If applied to an array type, the alignment requirement of the element type is instead returned. The operand is never evaluated.

alignas (_Alignas) can be used to force allocation at a given alignment.

Powered by Forestry.md