Detailed documentation for each feature in FPC Unleashed. Every feature has its own page with the full grammar, semantics, examples, and the modeswitch that gates it. All listed modeswitches are enabled by default in {$mode unleashed}; most can also be opted into from objfpc / delphi via {$modeswitch ...}.
Declare variables at point of first use inside any statement block, with explicit types, type inference (var x := expr), or as for-loop counters. Scope is the enclosing begin..end, with shadowing rules and interaction with the existing var section spelled out in detail.
Enabled via {$modeswitch inlinevars}.
A writeable static storage class with program-wide lifetime but block-local scope - the same idea as C's static int x; inside a function. Two flavors: a static declaration section (parallel to var / const, compile-time initializers, zero runtime cost) and a single-statement static name := expr; inline form (anywhere in a body, runtime initializers via a one-shot guard set true before the assignment, so a raised init leaves the variable zeroed and is not retried). Allowed only inside function / procedure / method bodies; at unit / program level plain var already gives the same lifetime and is the right tool.
Enabled via {$modeswitch staticsection} and {$modeswitch inlinestatic} (both on by default in unleashed).
Lightweight anonymous record types written in parentheses, e.g. (Integer, String) or (name: string; age: integer). Supports tuple literals, destructuring assignment, comparison, and works wherever a record works (function results, parameters, fields). Built on the existing record infrastructure, so managed types, copy semantics, and calling conventions are inherited for free.
Enabled via {$modeswitch tuples}.
Use if, case, and try as expressions that yield a value, so you can drop temporary variables for conditional assignment. Multi-statement branches use begin..end and the last expression in the block is the result.
Enabled via {$modeswitch statementexpressions}.
Pattern matching with first-match semantics that replaces case..of for non-ordinal subjects (tuples, strings, arbitrary expressions). Adds catch-all (_ / else), tuple wildcard patterns, condition-based branches, fallthrough mode, and an expression form that yields a value.
Enabled via {$modeswitch match}.
defer STATEMENT registers an action to fire at scope exit (LIFO, runs on normal exit / exception / break / continue / exit). autofree EXPR is sugar that turns a freshly-allocated class instance into a scoped resource with automatic Free. The with statement gains inline-var bindings (with var x := autofree T.Create do ...) so the holder is named, scoped, and cleaned up in one line. Cleanup uses a nil-guarded pattern so manual x.Free earlier in the scope does not double-free.
Enabled via {$modeswitch autofree}.
Initialize several variables of the same type in one declaration, e.g. a, b, c: integer = 42;. Works in var, typed constants, and inline var. Each variable gets an independent copy of the value - assigning to one does not affect the others.
Enabled via {$modeswitch multivarinit}.
step N clause in for loops to advance the counter by an arbitrary positive amount on each iteration. Works with to and downto, with inline var, and with all control-flow constructs (break, continue, exit, raise). The step expression is evaluated once before the loop starts; constant step 1 folds back to a regular for-loop. step is a context-sensitive keyword - only recognized between the to / downto expression and do, so existing code with a step variable / function / field keeps compiling.
Enabled via {$modeswitch forstep}.
C99-style records with a variable-length tail: data: array[] of T as the last field. The fixed header has the size sizeof reports; the tail extends as far as the allocation says it does, and indexing skips range checks because the FAM has no upper bound. Allocation is a single GetMem(rec, sizeof(rec)+payload), no separate buffer or pointer chase. Useful for Win32 structures with trailing arrays (TOKEN_GROUPS, BITMAPINFO, ...), network frames, file headers, and inline payloads.
Enabled via {$modeswitch flexiblearrays}.
Word-based modify-and-assign operators that the standard set is missing: div=, mod=, and=, or=, xor=, shl=, shr=.
Always available in every mode; no modeswitch and independent of {$coperators on}.
Builtin SwapValues(a, b) that swaps two same-typed assignable variables with a bitwise move, callable with no uses beyond the implicit System unit. For managed types (string, dynamic array, interface, Variant) it swaps the reference words with zero incr_ref / decr_ref churn; ordinals and pointer-sized operands lower to a register swap, larger types to a raw byte exchange. The point is to swap without dragging in SysUtils (Swap<T> / Exchange<T>) and its exception and handler setup. SwapValues is a fresh name with no RTL clash, and a user-declared SwapValues symbol shadows the builtin, so it never breaks existing code.
Unleashed-mode only; no separate modeswitch.
Compile-time Type(expr) that yields the static type of an expression without evaluating it. Works in every type-bearing position: var y: Type(x);, fields, parameters, function results, typecasts (Type(x)(v)), arguments to SizeOf / High / Low / Default, and derived types (array of Type(x), ^Type(x), set of Type(x), generic specialisation arguments). The operand is parsed and type-checked but never reaches code generation, so Type(a[0]) is safe on an empty dynamic array, Type(SomeFunc()) does not call SomeFunc, and range checks never fire on the operand. Composes with inline-var type inference, so a single var z := ... site can drive multiple downstream declarations spelled Type(z). Disambiguated from the type keyword purely by the trailing (, so type X = type Y strong aliases and ordinary type sections keep working unchanged.
Unleashed-mode only; no separate modeswitch.
Declare arrays of labels with numeric ranges (label state[0..4]) or string keys (label action['start', 'stop']) and jump to them by index. Useful for dispatch tables and state machines.
Available whenever {$goto on} is active; no dedicated modeswitch.
Record composition without duplicating fields, plus C-style memory overlap and per-field layout control. Three composition forms - embed TBase; flattens fields of an existing record into the outer scope (declaration-time duplicate detection rejects name collisions), record fields end; (and packed/bitpacked variants) does the same for an inline anonymous record, the classic name: T; keeps the regular named subfield. Modern union ... end; replaces case TYPE of for plain memory overlap, can appear anywhere in the body, multiple unions per record allowed; optional union size N (assert + pad in bytes) / union bitsize N (assert in bits, byte storage) / union align N (cache-line placement) / union of TYPE (size+align+default type anchor) modifiers. bitpacked record of TYPE plus innermost-wins propagation enables C-style name: N; bitfield syntax inside (translates to name: T bitsize N) and pad N; / pad 0; anonymous padding / alignment markers. Per-field modifiers align N / bitalign N / size N / bitsize N give byte- and bit-level layout control for faithful WinAPI / POSIX struct ports. OffsetOf() / BitOffsetOf() / AlignOf() / BitAlignOf() / BitSizeOf() intrinsics for compile-time layout introspection, honouring per-field overrides where applicable. GetMemAligned / AllocMemAligned / ReAllocMemAligned / FreeMemAligned in the system unit deliver aligned heap allocation for cache-line patterns.
Enabled via {$modeswitch composablerecords}.
Small semantic adjustments that make standard Pascal constructs behave the way most people expect them to. No dedicated modeswitch - these are unleashed-mode-only. Currently covers the preserved for-loop counter (for i := 1 to N do ... break; keeps the right value of i after the loop), with more entries to follow.
Catch-all page for smaller, targeted improvements that unlock Pascal patterns standard FPC modes reject - e.g. string-to-ordinal typecast in constant expressions (dword('RIFF')), Delphi-style implicit generic / specialize syntax made available in any mode via {$modeswitch implicitgenerics}, or the array[N] of T shorthand for array[0..N-1] of T. Some entries are gated on their own modeswitch (and enabled by default in unleashed), others are unleashed-only with no separate switch; each entry on the page states which.
Two delimiter forms for string literals spanning multiple source lines without manual + or LineEnding: backtick `...` (extended literal, embedded newlines tolerated) and a separate triple-quote form with indentation handling. They differ in tokenization and composition rules - the page covers both in depth, including escaping and interaction with concatenation. Stock FPC actually accepts these but never documented them; this page fills that gap.
Enabled via {$modeswitch multilinestrings}.
Embed expressions inside a string literal using $'Hello {name}, age {age:%2d}'. Two placeholder forms: bare {expr} (auto-format by type) and {expr:mask} where the mask is the raw text after the first : (Format / FormatDateTime / FormatFloat / IntToHex picked by type and mask shape). Default locale is invariant (L prefix opts into the system locale). The page covers the full type x mask dispatch table, escaping rules, required units, and notes for users coming from C# / Python / JavaScript.
Enabled via {$modeswitch interpolatedstrings}.
Replaces type-name strings emitted into RTTI / VMT structures with empty strings, so an ASCII dump of the binary no longer reveals the program's internal type structure. Comes with three whitelisting mechanisms: the expose keyword (per-declaration), the {$rttiexpose} directive (per-unit glob list), and the --rttiexpose= CLI flag (global glob list). The whitelisting decision is precomputed once per type at parse time and stored as a flag on the tdef, so RTTI emit stays cheap.
Enabled via {$modeswitch striprtti}. Off by default in unleashed mode.
Three CLI flags that override metadata fields the compiler embeds into the produced binary: --fpcsignature= (the .fpc.version ident string, every target), --linkerversion= (PE optional header linker version, Windows only), --osversion= (PE optional header minimum OS version, Windows only, accepts symbolic names like Win11 or numeric Major.Minor). Useful for distribution branding, build mimicry, and loader gating.
CLI-only; no directive form.
{$incfile NAME 'path'} reads the file at 'path' as raw bytes and emits a const NAME: String = '...'; at the directive site, with non-printable bytes encoded as #$nn escapes. Path resolution matches {$I} (absolute or searched in source dir / includepath). Useful for baking small assets (icons, schemas, lookup tables) directly into the binary without runtime file I/O.
Directive only; available in every mode.
Reference table of identifiers FPC Unleashed adds on top of stock FPC and that user code can call without an extra uses: compile-time intrinsics (OffsetOf, BitOffsetOf, AlignOf, BitAlignOf, extended BitSizeOf), and the aligned heap allocator in the system unit (GetMemAligned, AllocMemAligned, ReAllocMemAligned, FreeMemAligned). Each row lists the signature, category (intrinsic / RTL system / other RTL unit), gating modeswitch, and the feature page that covers the surrounding context.