P4043¶
- Code
P4043
- Message
General expression as a struct/FB-instance initializer value requires choosing a dialect or –allow-struct-initializer-expressions flag
This error occurs when a general (non-constant) expression is used as the
value in a structured or call-style initializer’s name := value pairs
(e.g. tonDelta : TON := (PT := pDevice^.Delta);) without the
--allow-struct-initializer-expressions compiler flag.
The IEC 61131-3 standard grammar for a structured initializer value
(Annex B) is
structure_element_initialization ::= structure_element_name ':=' (constant |
enumerated_value | array_initialization | structure_initialization). A
general expression – and in particular a pointer dereference plus member
access like pDevice^.Delta – is not one of those productions, so
accepting it is an extension used by TwinCAT and CODESYS, where such a
value is computed at instantiation time rather than being a compile-time
constant.
An ordinary constant, enumerated value, array initializer, or nested structure initializer is standard syntax and is always allowed.
Example¶
The following code will generate error P4043:
FUNCTION_BLOCK FB_Example
VAR
pDevice : REF_TO FB_Device;
tonDelta : TON := (PT := pDevice^.Delta);
END_VAR
END_FUNCTION_BLOCK
REF_TO is itself an extension, so this example needs
--allow-ref-to as well as the flag below. Not every dialect that enables
one enables the other, and some spell the pointer POINTER TO FB_Device
instead – see Enabling Dialects and Features for which
dialect enables which flag.
To fix this error, use a constant value:
FUNCTION_BLOCK FB_Example
VAR
tonDelta : TON := (PT := T#100MS);
END_VAR
END_FUNCTION_BLOCK
Or enable the extension:
Pass the --allow-struct-initializer-expressions flag to enable it, or select a dialect that includes it. See
Enabling Dialects and Features for the dialects and flags
reference.
What counts as a constant here¶
This error keys on the shape of the value, not on whether the value could
be computed at compile time. A single literal ((x := 1), (x := -1))
is a constant in the standard grammar and is always accepted; an
arithmetic expression over literals ((x := 1 + 1)) is not, and produces
this error even though its result is fixed.
That is the difference from
P4037 and
--allow-constant-initializer-expressions, which cover a plain VAR
initializer and do fold the expression to a literal. A structured
initializer value is not folded, because the extension exists for values
that genuinely cannot be – a pointer dereference read when the instance is
created. Write the computed value as a literal, or enable the flag above.
Think IronPLC is wrong about this?
If you believe this diagnostic is incorrect, open an issue on GitHub with a small sample that demonstrates the problem.