Skip to main content
_Complex is a built-in type specifier introduced in C99 used to declare variables that represent complex numbers. It modifies standard floating-point types to allocate contiguous memory for both a real and an imaginary component within a single scalar variable.

Type Variants

The _Complex keyword is not a standalone type. It must be explicitly combined with one of the three standard floating-point type specifiers to form a valid type. The C standard does not mandate specific bit-widths or representations (such as IEEE 754) for these underlying types.

The <complex.h> Header

While _Complex is a native compiler keyword, standard C practice utilizes the <complex.h> header. This header provides the complex macro (which expands to _Complex) and the I macro. According to the C standard, I expands to either _Complex_I or _Imaginary_I. It evaluates to a constant expression of type const float _Complex only if the implementation expands it to _Complex_I. If the compiler supports pure imaginary types, it expands to _Imaginary_I, which has the type const float _Imaginary.

Memory Layout and Alignment

The C standard guarantees that the memory layout and alignment of a _Complex type are strictly equivalent to an array of two elements of the corresponding real floating-point type.
  • Index 0: The real component.
  • Index 1: The imaginary component.
Because of this strict layout guarantee, it is safe to cast a pointer to a _Complex type into a pointer to its underlying real type to access the components directly.

Component Access and Initialization

While the I macro allows for algebraic initialization, C11 introduced the CMPLX, CMPLXF, and CMPLXL macros to construct complex numbers safely, avoiding edge cases with floating-point environments (like NaN or signed zeros). To extract components without pointer casting, the <complex.h> header provides strictly typed functions. For example, creal() and cimag() take a double complex argument and return a double. Corresponding functions exist for float (crealf(), cimagf()) and long double (creall(), cimagl()). True type-generic macros for complex numbers are provided separately by the <tgmath.h> header.

Native Arithmetic

The C standard explicitly defines the semantics and behavior of standard arithmetic operators (+, -, *, /) and assignment operators (+=, -=, *=, /=) when applied to _Complex types. The compiler automatically generates the underlying instructions to handle complex arithmetic rules (e.g., cross-multiplication for the * operator).
Tired of Poor C Skills? Fix That With Deep Grasping!Learn More