SA0130: Implicit expanding conversions
Detects code locations where conversions from smaller to larger data types are implicitly performed during arithmetic operations
Justification: The compiler permits any assignments of different types when the value range of the source type is completely contained within the value range of the target type. However, the compiler will build a conversion into the code as late as possible. For an assignment of type lint := dint * dint
, the compiler performs the implicit conversion only after multiplication:
lint := TO_LINT(dint * dint);
An overflow is therefore truncated. If you want to prevent this, then you can already convert the elements:
lint := TO_LINT(dint) * TO_LINT(dint);
Therefore, it may be useful to report locations where the compiler implements implicit conversions in order to check whether these are exactly what is intended. Furthermore, explicit conversions can be used to improve portability to other systems when those systems have more restrictive type checks.
Importance: Low
PROGRAM PLC_PRG VAR d : DINT; l : LINT; ui : UINT; uli : ULINT; usi : USINT; lw : LWORD; udi : UDINT; lr : LREAL; b : BYTE; END_VAR
(*The following lines could result in unwanted truncating by implicit conversions and should be reported with SA0130*) l := d * d; uli := usi * usi; lw := udi * udi; lr := b * b; d := ui * ui;
Output in the Messages view:
SA0130: Implicit expanding conversion from type 'DINT' to type 'LINT'
SA0130: Implicit expanding conversion from type 'USINT' to type 'ULINT'
SA0130: Implicit expanding conversion from type 'UDINT' to type 'LWORD'
SA0130: Implicit expanding conversion from type 'USINT' to type 'LREAL'
SA0130: Implicit expanding conversion from type 'UINT' to type 'DINT'