Generic

Overview

The _Generic keyword behaves similarly to a switch statement, but on the type of the controlling expression. It has form

_Generic(controlling expression,
  type1: ...,
  type2: ...,
  ...,
  typeN: ...)

The controlling expression is not evaluated. The type of the controlling expression is the type of the expression as if it had undergone an lvalue conversion (i.e. drops type qualifiers), array to pointer conversion, or function to pointer conversion.

A default type specifier can be used as a fallback if no other type specifier listed is compatible with the controlling expression. If a compatible type is found, the corresponding expression is used.

Type Inference

The auto storage class specifier can also be used for type inference. A definition of an inferred object must contain a direct declarator (e.g. no pointer indicators) and an assignment expression (e.g. no expressions which declare structs or unions). Optionally, the left-hand side may include type qualifiers or attributes.

The inferred type of an object is the type of the assignment expression after lvalue conversion (i.e. drops type qualifiers), array to pointer conversion, or function to pointer conversion.

An assignment of any other form is implementation-defined, if supported at all. For example, if the following auto assignments are supported, their behavior is implementation-defined:

double a = 1.0;
auto *p = &a;
auto p = (struct { int x; } *)0;

Typeof Operators

The typeof operators refer to the typeof and typeof_unqual operators. The former returns the exact type of the provided type name or that of the provided expression. The typeof_unqual operators works similarly, but strips top-level type qualifiers and _Atomic specifiers.

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

Powered by Forestry.md