Skip to main content

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

Example 55. Example
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:

  • sa_icon_message.png SA0130: Implicit expanding conversion from type 'DINT' to type 'LINT'

  • sa_icon_message.png SA0130: Implicit expanding conversion from type 'USINT' to type 'ULINT'

  • sa_icon_message.png SA0130: Implicit expanding conversion from type 'UDINT' to type 'LWORD'

  • sa_icon_message.png SA0130: Implicit expanding conversion from type 'USINT' to type 'LREAL'

  • sa_icon_message.png SA0130: Implicit expanding conversion from type 'UINT' to type 'DINT'