Typisierung von Ausdrücken
Neuron Power Engineer →typisiert →Ausdrücke und →Zuweisungen laut diesen Regeln:
-
Der Datentyp der →Variable, die das Ergebnis einer →überladenen Funktion erhält, beeinflusst den Datentyp des Ergebnisses für eine Funktion oder Operation. Diese Regel entspricht nicht den Vorgaben der →IEC-Norm.
Beispiele VAR
int1, int2, int3 : INT := 32767;
dint1 : DINT := 32767;
ResultInt1 : INT;
ResultDint1, ResultDint2 : DINT;
END_VAR
ResultInt1 := int1 + int2; (* The addition is performed as an INT-operation. *)
ResultDint1 := int1 + int2; (* In contrast to the IEC-standard: 'int1' and 'int2' are converted to DINT. The addition is performed as an DINT-operation and assigned to 'ResultDint1'. *)
ResultDint2 := dint1 + int3; (* 'int3' is converted to DINT. The addition is performed as a DINT addition. *)
-
Falls in den Ausdrücken gar kein konkreter Datentyp angeführt ist, wird die Typisierung ebenfalls vom Datentyp der Variable beeinflusst, die das Ergebnis einer überladenen Funktion erhält. Diese Zusatz-Regel ist eine implementierungsabhängige Realisierung, da die IEC-Norm keine Vorgaben dazu enthält.
Beispiele VAR
ResultDintA, ResultDintB, ResultDintC : DINT;
sint1 : SINT := 127;
END_VAR
ResultDintA := 127 + 127; (* The addition is performed as an DINT-operation because there is no other concrete data type. *)
ResultDintB := 127 + SINT#127; (* 'SINT#127' is converted to DINT. The addition is performed as an DINT-operation and assigned to 'ResultDintB'. *)
ResultDintC := 127 + sint1; (* 'sint1' is converted to DINT. The addition is performed as an DINT-operation and assigned to 'ResultDintC'.*)
-
Bei einem →Aufruf, der Eingänge, Ausgänge und/oder einen Ergebniswert mit dem gleichen →allgemeinen Datentyp verwendet, typisiert Neuron Power Engineer alle diese Eingänge, Ausgänge und den Ergebniswert des Aufrufs, sogar falls nur eines dieser Elemente mit einem konkreten Datentyp verbunden ist.
Beispiele VAR
Var1, OUT1 : INT;
iForceMrk1 : FORCEMRK;
END_VAR
Var1 := ADD(IN1 := 1, IN2 := 3);
(* The inputs and the return value of 'ADD' are using the same generic data type. As the INT variable 'Var1' is assigned to the call of 'ADD' (in particular to the return value of 'ADD'), the call is typed with 'INT'. Subsequently, the inputs of 'ADD' are typed with 'INT' as well. *)
iForceMrk1(IN := 3, OUT => OUT1);
(* The input and the output of 'FORCEMRK' are using the same generic data type. As output 'OUT' of 'iForceMrk1' is assigned to the INT variable 'OUT1', the call is typed with 'INT'. Subsequently, the input of 'iForceMrk1' is typed with 'INT' as well. *)
Falls ein →anwenderdefinierter Datentyp zur Typisierung verwendet wird, verwendet Neuron Power Engineer den →Basistyp. Diese Regel ist von Bedeutung, falls ein →Initialisierungswert im anwenderdefinierten Datentyp definiert ist – in diesem Fall wird nicht der Initialisierungswert des Datentyps verwendet, sondern der Initialisierungswert des Basistyps.
Vergleichen Sie: Bei einem →ARRAY-Datentyp (inkl. einerARRAY
-Deklaration einer Variable) oder einem →strukturiertem Datentyp ist der anwenderdefinierte Datentyp jedoch der Basistyp.Beispiele TYPE
MyInt : INT := 6;
MyStruct : Struct
Elem1 : MyInt;
END_STRUCT;
MyArray : Array [1..1] OF MyInt := [99];
END_TYPE
FUNCTION_BLOCK myFB
VAR
outDerived : MyInt;
outArray1 : MyArray;
outArray2 : Array [1..1] OF MyInt;
outStruct : MyStruct;
iForceMrk1, iForceMrk2, iForceMrk3, iForceMrk4 : FORCEMRK;
END_VAR
iForceMrk1(OUT => outDerived);
(* 'OUT' gets value '0' because initial value '0' of 'INT' is used. Here the base type is 'INT'. *)
(* The initial value '6' of 'MyInt' is NOT used. *)
iForceMrk2(OUT => outArray1);
iForceMrk3(OUT => outArray2);
iForceMrk4(OUT => outStruct);
(* Each element of output 'OUT' gets value '6' because initial value '6' of 'MyINT' is used. *)
(* Here the base type of each element is 'MyInt* while the base type of 'OUT' is 'ARRAY [...] OF' or 'STRUCT'. *)
END_FUNCTION_BLOCK
-
Falls 2 oder mehrere Aufrufe miteinander verbunden sind, bei denen die verbundenen Eingänge, Ausgänge und/oder der verbundene Ergebniswert von einem allgemeinen Datentyp sind (die anderen jedoch von einem konkreten Datentyp), typisiert Neuron Power Engineer alle diese Eingänge, Ausgänge und den Ergebniswert des Aufrufs auf den kleinsten gemeinsamen Datentyp.
Beispiel: BeimPACK
-Baustein ist der Ergebniswert vom allgemeinen DatentypANY_ELEMENTARY
und die Eingänge vom konkreten DatentypBYTE
, beimTO_DINT
-Baustein ist der Eingang ebenfalls vom allgemeinen DatentypANY_ELEMENTARY
und der Ergebniswert vom konkreten DatentypDINT
.
Für Versionen vor 3.25.0 und beim folgenden Code wurde der Ergebniswert vonPACK
und der Eingang vonTO_DINT
mitBOOL
typisiert (BOOL
ist der kleinster gemeinsame Datentyp vonANY_ALEMENTARY
).
Für Version 3.25.0 und nachfolgende Versionen wird der Code als fehlerhaft markiert, da der Ergebniswert vonPACK
in diesen Versionen nicht mit einem Baustein-Eingang eines allgemeinen Datentyps verbunden werden darf.Beispiel VAR
Var1 : DINT;
ByteVar1 : BYTE:= 16#AB;
END_VAR
Var1 := TO_DINT(PACK(ByteVar1, ByteVar1)); (* This line is highlighted as faulty in V3.25.0 and later. *)
Brechen Sie die Verschachtelung auf, um die Typisierung auf den kleinsten gemeinsamen Datentyp oder den für
PACK
gemeldeten Fehler zu umgehen.
Abhilfe 1: Erstellen Sie eine Hilfsvariable. Weisen Sie einen Aufruf dieser Hilfsvariable zu. Beim anderen Aufruf wiesen Sie diese Hilfsvariable als Parameter zu.Beispiel für Abhilfe 1
VAR
Var1 : DINT;
ByteVar1 : BYTE := 16#AB;
HelperVar : DINT; (* the auxiliary variable *)
END_VAR
HelperVar := PACK(ByteVar1, ByteVar1);
Var1 := TO_DINT(HelperVar); (* 'Var1' evaluates to value '43947'. This a value as expected from 'PACK' *)
Abhilfe 2: Erstellen Sie eine benutzerdefinierte POE (z.B. eine Funktion). Weisen Sie einen Aufruf der Bausteine (im folgenden Beispiel:
PACK
) dem Ergebniswert der Funktion zu. Rufen Sie die Funktion als Parameter des anderen Bausteins (dann:DINT
) auf.Beispiel für Abhilfe 2 FUNCTION myFun1 : DWORD
VAR
ByteVar1 : BYTE:= 16#AB;
END_VAR
myFun1 := PACK(ByteVar1, ByteVar1); (* 'PACK' is assigned to the return value of function 'myFun1'. *)
END_FUNCTION
FUNCTION_BLOCK myFB2
VAR
Var1 : DINT;
END_VAR
Var1 := TO_DINT(IN:=myFun1()); (* 'Var1' evaluates to value '43947'. This a value as expected from 'PACK'. *)
END_FUNCTION_BLOCK