Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

E0032: a value the standard requires constant that is not

Some values are fixed when the program is compiled, and the standard says they are constant expressions (Ed.3 6.4.4.5.1, 6.4.4.4, 6.6.1.2.4, 7.3.3.3.3):

  • an array’s bounds, ARRAY[1..N];
  • a STRING’s length, STRING[N];
  • a subrange’s limits, INT (0..N);
  • a CASE’s labels on an integer, N: and 1..N: (Ed.3 7.3.3.3.3).

A constant expression is made of integer literals, + - * / MOD and parentheses, and the names of constants: a VAR CONSTANT of the POU, or a VAR_GLOBAL CONSTANT (through its VAR_EXTERNAL CONSTANT, or seen directly from a TYPE, as a CODESYS GVL’s constants are). The constant is of an integer type and has an initial value that is itself a constant expression.

VAR CONSTANT
    N : INT := 10;
END_VAR
VAR
    n : INT := 10;
    a : ARRAY[1..N] OF REAL;      (* fine *)
    b : ARRAY[1..n] OF REAL;      (* E0032: n is a variable *)
END_VAR

An initial value is a constant expression too (Ed.3 6.6.1.2.4, Figure 6), of any elementary type: literals, constants, the operators and the standard functions on them (Initial values). A variable there, or the result of a FUNCTION of the program’s, is known only as the program runs:

VAR
    n : INT := 10;
    a : INT := n + 1;             (* E0032: 'n' is a variable *)
    b : INT := Twice(2);          (* E0032: the result of Twice *)
END_VAR

Set such a variable in the body instead, at the first cycle.

A constant expression that has no value is refused too, in an initial value as well as in a bound: a division by zero, a shift by a negative count, a MUX selecting an input it has not, an index outside a constant array, and a constant whose initial value names the constant itself.

VAR CONSTANT
    Z : INT := 0;
    KA : ARRAY[1..3] OF INT := [4, 5, 6];
    A : INT := B;                 (* E0032 where A is used: A is B is A *)
    B : INT := A;
END_VAR
VAR
    x : INT := 10 / Z;            (* E0032: divides by zero *)
    w : WORD := SHL(16#01, -1);   (* E0032: shifts by a negative count *)
    m : INT := MUX(2, 5, 6);      (* E0032: MUX's inputs are 0 and 1 *)
    e : INT := KA[4];             (* E0032: KA is ARRAY[1..3] *)
END_VAR

For an array whose size is the caller’s, use ARRAY[*] (Ed.3 6.5.3, E0033).