FOR loop

Syntax

FOR <loop_var> := <start_expr> TO <end_expr> [BY <step_expr>] DO
    <statement_list>
END_FOR;
  • <loop_var> is an existing integer variable. ST does not let you declare it inline (unlike C++ for (int i...).
  • <start_expr> and <end_expr> must be integer expressions of the same type as <loop_var>.
  • <step_expr> is optional; defaults to +1. Must be of the same type as <loop_var> and may be negative.

Semantics

Per IEC 61131-3 clause 6.6.3.4:

  1. Evaluate <start_expr>, <end_expr>, <step_expr> once. Subsequent changes to those source expressions inside the body have no effect on the loop bounds.
  2. Set <loop_var> to the start value.
  3. If <step_expr> >= 0 and <loop_var> > <end_expr>, exit. If <step_expr> < 0 and <loop_var> < <end_expr>, exit.
  4. Run the body.
  5. <loop_var> := <loop_var> + <step_expr>.
  6. Goto step 3.

The loop variable is not valid after the loop ends. The last value depends on the implementation; matiec leaves it at end + step.

Examples

(* Sum an array *)
iSum := 0;
FOR i := 1 TO 10 DO
    iSum := iSum + arr[i];
END_FOR;

(* Reverse iteration *)
FOR i := 10 TO 1 BY -1 DO
    arr[11 - i] := arr[i];
END_FOR;

(* Skip every second *)
FOR i := 0 TO 100 BY 2 DO
    arrEven[i / 2] := arr[i];
END_FOR;

(* Early exit on found *)
iFound := -1;
FOR i := 0 TO 99 DO
    IF arr[i] = TARGET THEN
        iFound := i;
        EXIT;
    END_IF;
END_FOR;

Scan-cycle warning

A FOR i := 1 TO 1000 DO that does substantial work per iteration easily eats your scan cycle. Cap the loop length at compile time, profile the body, and split into per-cycle chunks if needed (use a persistent counter variable that the POU advances by N per scan).

IEC reference

IEC 61131-3 third edition (2013), clause 6.6.3.4 — “FOR statement”.

matiec conformance

matiec implements FOR per the standard. The three pitfalls in llm_signals are real and reproducible:

  • Type-strict bounds (no auto-promotion).
  • Silent zero-iteration when BY sign and start/end direction disagree.
  • Need for explicit BY -1 when iterating downward.