# Flash Variables & Constants In Flash, values are declared with explicit mutability control. You can declare values using `var`, `const`, or the short-hand initialization operator `:=`. --- ## 1. Variable Declarations (`var`) Variables declared with `var` are **mutable**; their values can be modified after initialization. * **With Explicit Type:** Specify the type between the name and the `=` operator. * **With Inferred Type:** Omit the type, and the compiler will infer it from the right-hand side expression. ```flash // Explicit type var count i32 = 0 count = count + 1 // OK // Inferred type var factor = 2.5 factor = factor * 2.0 // OK ``` --- ## 2. Constant Declarations (`const`) Constants declared with `const` are **immutable**. Once initialized, their value cannot be changed. * Like variables, you can either provide an explicit type or let the compiler infer it. ```flash // Explicit type const MAX_BUFFER usize = 1024 // Inferred type const greeting = "Hello, Flash!\n" // MAX_BUFFER = 512 // Compiler error downstream! ``` --- ## 3. Short-hand Declaration (`:=`) For quick bindings where you want the type to be inferred, Flash provides the `:=` short-hand syntax. **Important:** Short-hand declarations using `:=` are **immutable** (constant) by default. They are a convenient syntactic sugar for `const name = expression`. ```flash // Syntax: name := expression (equivalent to const name = expression) msg := "hello\n" // Inferred as constant string slice []const u8 // msg = "world" // Compiler error downstream! ``` > [!NOTE] > `:=` is the **canonical** spelling for an untyped immutable local. Running `flashc fmt` rewrites an untyped `const name = expr` into the `name := expr` short-hand automatically, so formatted Flash uses `:=` consistently. A `const` that carries an explicit type — `const MAX usize = 1024` — is left exactly as written. --- ## 4. Destructuring A tuple value — most often a multi-value return (see Chapter 5) — unpacks into several names in one statement. One keyword rules all the names: `:=` declares every target immutably, `var … =` declares every target mutably. ```flash // Both names declared immutably q, r := divmod(7, 2) // Both names declared mutably var x, y = pair() // _ skips a position you do not need tok, _ := next() ``` Existing lvalues — including member and index targets — take a **destructuring assignment** with plain `=`: ```flash x, arr[0] = pair() ``` A few rules keep the form unambiguous: a `:=` target must be a plain name (assign to members or indices with `=`), a compound operator like `+=` cannot destructure, and a destructure that discards every position is written `_ = expr` instead. --- ## 5. Undefined Values In low-level systems programming, you often want to allocate space for a variable without spending CPU cycles initializing it. Flash allows you to initialize a variable as `undefined`. ```flash use flibc export fn main(_ usize, _ argv) noreturn { // Allocate 512 bytes on the stack without initializing var buffer [512]u8 = undefined // Fill it via a read syscall _ = flibc.sys.read(0, &buffer, buffer.len) flibc.exit() } ``` > [!WARNING] > Accessing a variable initialized to `undefined` before writing to it results in undefined behavior. Use with care. --- ## 6. Alignment & Section Placement (`align`, `linksection`) A binding can pin the alignment of its storage with `align(N)`, written between the type and the `=`: ```flash // A page-aligned buffer — valid at file scope and inside functions var pool [4096]u8 align(4096) = undefined ``` The form works on locals and on file-scope bindings alike, `extern var` included (the alignment becomes part of the symbol's contract). A file-scope binding can also name the **linker section** its symbol lands in with `linksection("…")`, in the same slot (after any `align`): ```flash // Pin read-only data where the linker script expects it const PAD [4096]u8 linksection(".rodata") = [_]u8{0} ** 4096 ``` Two boundaries: an `extern var` cannot carry a `linksection` (the defining object owns the section), and a local binding cannot either (a stack slot lives in no section). Functions take the attribute too, between the parameter list and any `callconv(…)`.