Skip to main content

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:

Beispiel 78. Beispiel
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

Beispiel 79. Beispiel
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:

  • sa_icon_message.png SA0066: Verwendung von Zwischenergebnissen (byTest - USINT #1)