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.