> Agent-readable docs index: /llms.txt. Download /docs.zip to grep all markdown files locally.

---
$schema: https://holocron.so/frontmatter.json
title: Types and Variables
description: IEC 61131-3 types, VAR blocks, direct addresses, RETAIN, and cross-POU visibility rules.
icon: lucide:variable
---

## Elementary and derived types

The IR and supported parser paths model:

* **Elementary type names** (`BOOL`, `INT`, `REAL`, `TIME`, `STRING`, date/time types, and related names)
* Type aliases, enumerations, and subranges
* Arrays and structures with initializer and bound checks
* Fixed-length strings (`STRING[n]`)

Semantic checking covers assignment compatibility, subrange membership, enum use, aggregate indexing, conversion ranges, and direct-variable validation. See the compliance matrix rows under **`types.*`** and **`variables.*`** for the tracked surface.

**Repeated array initializer** syntax is supported, for example `[4(0)]` in `examples/all_data_types.st`.

**String and WSTRING literals** support IEC `$` escapes and `$xx` hex byte escapes in character strings.

## Variable blocks

| Block                                             | Typical use                                               |
| ------------------------------------------------- | --------------------------------------------------------- |
| `VAR` / `VAR_INPUT` / `VAR_OUTPUT` / `VAR_IN_OUT` | POU-local and interface variables                         |
| `VAR_GLOBAL`                                      | Configuration-wide globals                                |
| `VAR_EXTERNAL`                                    | External references to matching `VAR_GLOBAL` declarations |
| `VAR_TEMP`                                        | Temporary locals (cannot be `RETAIN`)                     |
| `VAR_CONFIG`                                      | Configured variables at addresses                         |
| `VAR_ACCESS`                                      | Access path declarations                                  |

**`CONSTANT`** variables are checked for illegal writes. `RETAIN` and `NON_RETAIN` are validated for allowed block combinations.

### VAR\_EXTERNAL rules

Every **`VAR_EXTERNAL`** declaration must match a project **`VAR_GLOBAL`** by name and type. **`CONSTANT`** consistency is enforced between external and global declarations. A missing global produces a semantic error.

### Edge input qualifiers

**`R_EDGE`** and **`F_EDGE`** are allowed only on **`FUNCTION_BLOCK`** **`VAR_INPUT`** variables of type **`BOOL`**. Using them on programs, functions, or non-BOOL inputs is rejected at check time.

### VAR\_ACCESS restrictions

**`VAR_ACCESS`** paths cannot target variables declared in **`VAR_TEMP`**, **`VAR_EXTERNAL`**, or **`VAR_IN_OUT`** blocks.

<Aside>
  <Info>
    **VAR\_IN\_OUT** alias semantics are enforced for user function blocks. Non-variable actuals are rejected at check time.
  </Info>
</Aside>

## Locations and direct variables

Variables may use **`AT`** with direct variable syntax, for example `%MW10` or `%MX0.0`. The lexer and semantics validate direct variable forms used in examples such as `configuration.st`.

Incomplete located variables (`%I*`, `%Q*`, `%M*` with optional size prefix) are supported in declarations. Wildcard direct references in executable code are rejected.

Generated C emits **`rbcpp_io_symbols`** metadata (name, IEC location, direction, C type, size) so target code can bind `%I`, `%Q`, and `%M` storage without guessing layout.

## VAR\_ACCESS in simulation and C

**`VAR_ACCESS`** paths are validated at check time and appear in configuration **`run`** traces. The simulator supports **`--access`** write injection for `READ_WRITE` paths.

Generated C includes **`_read_access_path`** and **`_write_access_path`** helpers for simple, nested structure, and function-block field paths. **`READ_ONLY`** paths are enforced in generated services.

The **`rbcpp_target`** crate can bind access paths to retained program state or external I/O (file-backed HAL, Modbus, EtherCAT, ROS 2 parameters) through **`AccessRuntime`** and **`TargetSupervisor`**. Certified target lifecycle semantics remain outside the IEC compiler.

<Aside>
  <Info>
    Use **`--access [CYCLE:]NAME=VALUE`** on **`run`** to inject writes in the simulator. See [Execution model](/execution-model) and [Targets and Generated C](/targets).
  </Info>
</Aside>

## Initial values

Initializers are parsed and checked for basic compatibility. Aggregate initializers are supported for arrays and structures in the supported ST subset.

## RETAIN and warm restart

**`RETAIN`** variables keep their runtime values when the interpreter performs a warm restart. `NON_RETAIN` locals and non-retained state reset to initializer values. The C backend emits separate cold and warm-restart entry points for program state.

<Warning>
  `FUNCTION` POUs cannot declare `RETAIN` variables. `VAR_TEMP RETAIN` and `VAR CONSTANT RETAIN` combinations are rejected at check time.
</Warning>

## Cross-POU visibility

Semantic checking models visibility for configuration and resource **`VAR_GLOBAL`** declarations when resolving references across POUs in the same project.

## Examples

| File                | Focus                                              |
| ------------------- | -------------------------------------------------- |
| `all_data_types.st` | Elementary types, typed literals, enums, subranges |
| `aggregates.st`     | Arrays and structures                              |
| `strings_dates.st`  | Strings and date/time literals                     |
| `configuration.st`  | `VAR_GLOBAL`, `VAR_CONFIG`, `VAR_ACCESS`           |
| `conversions.st`    | Typed conversions                                  |


---

*Powered by [holocron.so](https://holocron.so)*
