# Arrays

Arrays are fixed-size, stack-allocated, and bounds-checked.

```cplus
let a: [i32; 4] = [10, 20, 30, 40];
let x: i32 = a[2];               // 30; an out-of-range index traps

let mut buf: [i32; 4] = [0, 0, 0, 0];
buf[0] = 5;

for i in 0..4 {
    println(a[i as usize]);
}
```

**Use small `[u8; N]` arrays for scratch buffers in hot loops.** They live on the stack (or in registers after SROA), whereas `malloc` is real heap allocation that dominates tight loops.

## Fill-array literal `[EXPR; N]`

`[EXPR; N]` is an array of `N` copies of `EXPR`. The codegen fast-paths the `[0u8; N]` zero-fill to a single `llvm.memset` (essential for kilobyte-scale stack buffers); other shapes lower to a tight N-iteration store loop the optimizer unrolls.

```cplus
let zeros: [u8; 64]    = [0u8; 64];       // memset fast path
let ones:  [i32; 4]    = [1; 4];          // (1, 1, 1, 1)
let bytes: [u8; 16384] = [0u8; 16384];    // 16 KiB zero buffer, single memset
```

The count is a `u32` literal, or a non-negative integer `const` name. The same `[T; N]` array-*type* length also accepts a `const` name, so a fixed buffer size lives in one place and is referenced everywhere:

```cplus
const CAP: usize = 1024;
let scratch: [u8; CAP] = [0u8; CAP];   // const drives both the type length and the fill
```

The name must resolve to a `const` with a non-negative integer-literal initializer in scope; anything else is **E0X36**.
