SA0066: Verwendung von Zwischenergebnissen
Funktion | 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 | TwinCAT 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:
In TwinCAT ist bError 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:
|
Wichtigkeit | Niedrig |
![]() | 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! |
Beispiel:
PROGRAM MAIN
VAR
nBYTE : BYTE;
nDINT : DINT;
nLINT : LINT;
bResult : BOOL;
END_VAR//=====================================================================================================
// type size smaller than register size
// use of temporary result + implicit casting => SA0066
bResult := ((nBYTE - 1) <> 255); // => SA0066
// correcting this code by explicit cast so that the type size is equal to or bigger than register size
bResult := ((BYTE_TO_LINT(nBYTE) - 1) <> 255); // no error
bResult := ((BYTE_TO_LINT(nBYTE) - LINT#1) <> LINT#255); // no error
//=====================================================================================================
// result depends on solution platform
bResult := ((nDINT - 1) <> 255); // no error on x86 solution platform
// => SA0066 on x64 solution platform
// correcting this code by explicit cast so that the type size is equal to or bigger than register size
bResult := ((DINT_TO_LINT(nDINT) - LINT#1) <> LINT#255); // no error
//=====================================================================================================
// type size equal to or bigger than register size
// use of temporary result and no implicit casting => no error
bResult := ((nLINT - 1) <> 255); // no error
//====================================================================================================