SA0066: Uses of temporary resultsPermalink

Detects the use of temporary results in statements with a data type that is less than the registry size. The implicit cast in this case may lead to unwanted results.

Justification: For performance reasons, CODESYS performs operations on the register width of the processor. Intermediate results are not truncated. This can lead to misinterpretations as in the following case: ‎usintTest := 0; xError := usintTest - 1 <> 255;‎. In CODESYS, ‎xError‎ is ‎TRUE‎ in this case because the operation ‎usintTest - 1‎ is typically executed as a 32-bit operation and the result is not cast to the byte size. Then the value ‎16#ffffffff‎ (not equal to 255) is located in the registry. To avoid this, you have to cast the intermediate result explicitly: ‎xError := TO_USINT(usintTest - 1) <> 255; ‎

NOTICE

NOTICE
NOTICE
NOTICE

NOTICE

NOTICE

If this message is activated, then many less problematic locations in the code will be reported. Although a problem can only occur when the operation produces an overflow or underflow in the data type, the static analysis cannot differentiate between the individual locations.

If you include an explicit typecast in all reported locations, then the code will be much slower and less readable.

Importance: Low

Example

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

--> SA0066: Use of temporary result: (byTest - USINT #1)