SA0066: Verwendung von Zwischenergebnissen
Ermittelt Verwendungen von Zwischenergebnissen in Anweisungen mit einem Datentyp, der kleiner als die Registergröße ist. In diesem Fall führt der implizite Cast gegebenenfalls zu unerwünschten Ergebnissen.
Begründung: CODESYS Static Analysis führt aus Performancegründen Operationen auf der Registerbreite des Prozessors aus. Zwischenergebnisse werden nicht abgeschnitten! Das kann zu Fehlinterpretationen führen, wie im folgenden Fall:
usintTest := 0; xError := usintTest - 1 <> 255;
In CODESYS ist xError
in diesem Fall TRUE
, weil die Operation usintTest - 1
typischerweise als 32-Bit-Operation ausgeführt wird und das Ergebnis nicht auf die Größe von Byte gecastet wird. Im Register steht dann der Wert 16#ffffffff
und dieser ist ungleich 255.
Um dies zu umgehen müssen Sie das Zwischenergebnis explizit casten:
xError := TO_USINT(usintTest - 1) <> 255;
Wichtig
Wenn diese Meldung aktiviert ist, werden sehr viele eher unproblematische Stellen im Code gemeldet werden. Ein Problem kann zwar nur entstehen, wenn die Operation einen Überlauf oder Unterlauf im Datentyp produziert, die statische Analyse kann dies aber für die einzelnen Stellen nicht differenziert erkennen.
Wenn Sie an allen gemeldeten Stellen einen expliziten Typcast einbauen, dann wird der Code deutlich langsamer und unleserlicher!
Wichtigkeit: Niedrig
PROGRAM PLC_PRG VAR byTest:BYTE; liTest:LINT; xError:BOOL; END_VAR
//type size smaller than register size; byTest := 0; IF (byTest - 1) <> 255 THEN //use of temporary result + implicit casting -> SA0066 xError := TRUE; ELSE xError := FALSE; END_IF //type size equal to or bigger than register size; liTest := 0; IF (liTest - 1) <> -1 THEN // use of temporary result and no implicit casting -> OK xError := TRUE; ELSE xError := FALSE; END_IF
Ausgabe unter Ansicht Meldungen:
SA0066: Verwendung von Zwischenergebnissen (byTest - USINT #1)