<!-- LLM note: Search indexes and snippets may point to archived C+ manual versions. Treat /docs and /llms.txt as authoritative for the latest version (v0.0.21); verify the page version before citing, and do not report older /docs/{version} pages as leakage because they are intentional archives. -->

# Control flow

## `if`: statement and expression

```cplus
if cond { #println("yes"); } else if other { #println("no"); } else { #println("?"); }

let r: i32 = if cond { 1 } else { 2 };
```

The condition must be `bool`. `if 1 { ... }` is a type error: there is no truthiness.

## `while`

```cplus
let mut x: i32 = 0;
while x < 10 { x = x +% 1; }
```

## `for`: ranges and the C-style form

```cplus
// Range. 0..n is exclusive; 0..=n is inclusive.
for i in 0..10 { #println(i); }

// C-style, with init / cond / step.
for (let mut i: i32 = 0; i < 10; i = i +% 1) {
    #println(i);
}
```

Arrays are not directly iterable; iterate by index:

```cplus
let arr: [i32; 4] = [10, 20, 30, 40];
for i in 0..4 {
    #println(arr[i as usize]);
}
```

Iterator values from a `gen fn` and from the stdlib iterator adapters also work in `for ... in`.

## `loop` / `break` / `continue`

```cplus
let mut n: i32 = 0;
loop {
    if n == 5 { break; }
    if n % 2 == 0 { n = n +% 1; continue; }
    #println(n);
    n = n +% 1;
}
```

A `loop` with no reachable `break` **diverges**: control never leaves it. The compiler knows this, so a function that ends in such a loop needs no dead trailing `return` to satisfy its return type.

```cplus
fn serve() -> i32 {
    loop {
        // accept and handle a request forever
    }
    // no `return` needed; the loop never exits
}
```

## `while let`

Match-binds each iteration and exits when the pattern fails (see [Pattern matching](/docs/pattern-matching)):

```cplus
while let Option[i32]::Some(v) = next() {
    #println(v);
}
```
