SA0065: Incorrect pointer addition to base size

Function

Determines pointer additions in which the value to be added does not match the basic data size of the pointer. Only literals of the base data size and multiples thereof can be added without error.

Reason

In TwinCAT (in contrast to C and C++), when a pointer with an integer value is added, only this integer value is added as the number of bytes, not the integer value multiplied by the base size.

pINT := ADR(array_of_int[0]);
pINT := pINT + 2 ; // in TwinCAT zeigt pINT anschließend auf array_of_int[1]

This code would work differently in C:

short* pShort
pShort = &(array_of_short[0])
pShort = pShort + 2; // in C zeigt pShort anschließend auf array_of_short[2]

In TwinCAT, a multiple of the basic size of the pointer should therefore always be added to a pointer. Otherwise, the pointer may point to a not aligned memory, which (depending on the processor) can lead to an alignment exception on access.

Importance

High

Samples:

PROGRAM MAIN
VAR
    pUDINT : POINTER TO UDINT;
    nVar   : UDINT;
    pREAL  : POINTER TO REAL;
    fVar   : REAL;
END_VAR
pUDINT := ADR(nVar) + 4;
pUDINT := ADR(nVar) + (2 + 2);
pUDINT := ADR(nVar) + SIZEOF(UDINT);
pUDINT := ADR(nVar) + 3;                            // => SA0065
pUDINT := ADR(nVar) + 2*SIZEOF(UDINT);              // => SA0065
pUDINT := ADR(nVar) + (3 + 2);                      // => SA0065
 
pREAL  := ADR(fVar);
pREAL  := pREAL + 4;
pREAL  := pREAL + (2 + 2);
pREAL  := pREAL + SIZEOF(REAL);
pREAL  := pREAL + 1;                                // => SA0065
pREAL  := pREAL + 2;                                // => SA0065
pREAL  := pREAL + 3;                                // => SA0065
pREAL  := pREAL + (SIZEOF(REAL) - 1);               // => SA0065
pREAL  := pREAL + (1 + 4);                          // => SA0065