POINTER

At runtime, a pointer saves the memory address of objects such as variables or function block instances.

Syntax

<pointer name>: POINTER TO <data type> | <data unit type> | <function block name>;

Sample

FUNCTION_BLOCK FB_Sample
VAR
    pSample : POINTER TO INT;
    nVar1 : INT := 5;
    nVar2 : INT;
END_VAR
pSample := ADR(nVar1);  // pointer pSample is assigned to address of nVar1 
nVar2 := pSample^;      // value 5 of nVar1 is assigned to variable nVar2 by dereferencing of pointer pSample 

Dereferencing a pointer means obtaining the value to which the pointer points. A pointer is dereferenced by appending the content operator ^ to the pointer identifier, for example pSample^ in the sample shown above. To assign the address of an object to a pointer, use the address operator ADR: ADR(nVar1).

In online mode, you can use the Go to reference command to jump from a pointer to the declaration location of the referenced object (available from TC3.1 Build 4026).

POINTER 1:

If a pointer to an allocated input variable is used, the access is interpreted as write access. This leads to the compiler warning "<Pointer Name> is not a valid assignment target" during code generation.

Sample: pTest := ADR(nInput);

If you need a construct of this type, you must first copy the input value (nInput) to a variable with write access.

Index access to pointers

TwinCAT allows index access [ ] to variables of type POINTER, as well as to the data types STRING or WSTRING.

The data to which the pointer points can also be accessed by appending the bracket operator [] to the pointer identifier, for example pData[i]. The basic data type of the pointer determines the data type and the size of the indexed component. The index access to the pointer takes place arithmetically by adding the index-dependent offset i * SIZEOF(<base type>) to the address of the pointer. The pointer is implicitly dereferenced at the same time. Calculation: pData[i] :=(pData + i * SIZEOF(INT))^;

Index access to STRING

If you use index access for a variable of type STRING, you get the character at the offset of the index expression. The result is of type BYTE. For example, sData[i] returns the ith character of the string sData as SINT (ASCII).

Index access WSTRING

If you use index access for a variable of type WSTRING, you get the character at the offset of the index expression. The result is of type WORD. For example, wsData[i] returns the ith character of the string as INT (Unicode).

Subtracting pointers

The result of the difference between two pointers is a value of the type DWORD, even on 64-bit platforms, if the pointers are 64-bit pointers.

POINTER 2:

Note the possibility of using references. The advantage of using references is that type safety is guaranteed. That is not the case with pointers.

POINTER 3:

The memory access of pointers during runtime can be checked by the implicit monitoring function CheckPointer.

Automatic pointer/reference update during Online Change

POINTER 4:

Available from TwinCAT 3.1 Build 4026

The following descriptions refer to both pointers and references. For ease of reading, however, only the term pointer is used in the following.

Function:

During an Online Change, the values of all PLC pointers are automatically updated so that the respective pointer refers to the same variable or the same object as before the Online Change. This means that a pointer remains valid after the Online Change, even if the variable it points to is moved to a different memory position during the Online Change.

Mode of operation:

During an Online Change, a check is made for each pointer to see whether it refers to a PLC symbol. The following requirements must be met for such a determination.

Requirements:

Additional update option:

The functionality described is available from TwinCAT 3.1 Build 4026. Any previous, manually implemented mechanism for updating a pointer can still be used. The desired destination can be assigned to the pointer cyclically, for example. There is no need to remove these lines of code from the project. Similarly, it is not necessary to keep or implement these lines of code.

See also: