REFERENCE
A reference points implicitly to another object. The assignment is made with the operator REF=
. The reference is implicitly dereferenced during the access and therefore requires no special content operator ^
like a pointer.
Syntax
<identifier> : REFERENCE TO <data type> ;
<data type> : base type of the reference
Sample declaration:
PROGRAM MAIN
VAR
refInt : REFERENCE TO INT;
nA : INT;
nB : INT;
END_VAR
You can now use refInt as "alias" for variables of type INT.
![]() | TwinCAT initializes references (with 0). |
Invalid declarations:
aRefInt : ARRAY[0..9] OF REFERENCE TO INT;
pRefInt : POINTER TO REFERENCE TO INT;
refRefInt : REFERENCE TO REFERENCE TO INT;
refBit : REFERENCE TO BIT;
A reference type may not be used as the base type of an array, pointer or a reference. In addition, a reference may not point to a bit variable. Such constructs generate compiler errors.
The readability of a program is made more difficult if the same memory cell is accessed simultaneously via an identifier and its alias (e.g. refInt and nA).
Assignment
Allocation operator REF=
The operator generates a reference (pointer) to a value.
Syntax:
<variable name> REF= <variable name>
Sample:
PROGRAM MAIN
VAR
refA : REFERENCE TO ST_Sample;
stA : ST_Sample;
refB : REFERENCE TO ST_Sample;
stB1 : ST_Sample;
stB2 : ST_Sample;
END_VAR
refA REF= stA; // represents => refA := ADR(stA);
refB REF= stB1; // represents => refB := ADR(stB1);
refA := refB; // represents => refA^ := refB^; (value assignment of refB as refA and refB are implicitly dereferenced)
refB := stB2; // represents => refB^ := stB2; (value assignment of stB2 as refB is implicitly dereferenced)
END_VAR
If references are assigned with :=
, a value is always copied, regardless of whether the reference is on the left, right or on both sides:
refA := value
writes the valuevalue
to the location referred to by the reference. In pointer notation:refA^ := value
value := refA
writes the value to which the reference refers tovalue
. In pointer notation:value := refA^
refA := refB
writes the value referenced byrefB
to the location referenced byrefA
. In pointer notation:refA^ := refB^
If REF=
is used, the address is always adopted and there must be a reference on the left-hand side:
refA REF= value
: The reference refers tovalue
. In pointer notation:refA := ADR(value)
refA REF= refB
:refA
refers to the same value asrefB
. In pointer notationrefA := refB
value REF= refA
leads to a compile error
In the declaration, REFERENCE TO INT REF= value
behaves like REFERENCE TO INT := value
References as input
You have to set the address of the reference via a separate assignment operation with the help of the assignment operator REF=. An exception to this is when an input is a REFERENCE TO and the input is transferred within the call. In this case the normal allocation operator := is used instead of the allocation operator REF=.
FUNCTION_BLOCK FB_Sample
VAR_INPUT
refInput1 : REFERENCE TO INT;
refInput2 : REFERENCE TO INT;
END_VAR
PROGRAM MAIN
VAR
fbSample : FB_Sample;
n1 : INT;
n2 : INT;
END_VAR
fbSample.refInput1 REF= n1;
fbSample(refInput2 := n2);
Application example:
refInt REF= nA; // refInt points now to nA
refInt := 12; // nA has got the value 12
nB := refInt * 2; // nB has got the value 24
refInt REF= nB; // refInt points now to nB
refInt := nA / 2; // nB has got the value 6
refInt REF= 0; // explicit initialization of the reference
You can check whether a reference points to a valid value (e.g. not equal to 0) with the help of a special operator (see Checking references for validity).
Comparison of reference and pointer
In comparison with a pointer, a reference has the following advantages:
- Easier to use:
- A reference can directly access the contents of the referenced object without dereferencing.
- Nicer and simpler syntax when transferring values:
- Calling a function block that transfers a reference without address operator instead of a pointer.
- Sample:
FB_Test1(refInput := nValue);
instead of:FB_Test2(pInput := ADR(nValue));
- Type safety:
- When assigning two references, the compiler checks whether the base types match. This is not checked in the case of pointers.
Checking references for validity
You can use the operator __ISVALIDREF
to check whether a reference points to a valid value, i.e. a value not equal to 0.
Syntax:
<boolesche Variable> := __ISVALIDREF(<mit REFERENCE TO <datatype> deklarierter Kennzeichner>);
The boolean variable becomes TRUE if the reference points to a valid value, otherwise FALSE.
Sample
PROGRAM_MAIN
VAR
nVar : INT;
refInt1 : REFERENCE TO INT;
refInt2 : REFERENCE TO INT;
bTestRef1 : BOOL := FALSE;
bTestRef2 : BOOL := FALSE;
END_VAR
nVar := nVar + 1;
refInt1 REF= nVar;
refInt2 REF= 0;
bTestRef1 := __ISVALIDREF(refInt1); (* becomes TRUE, because refInt1 points to nVar, which is non-zero *)
bTestRef2 := __ISVALIDREF(refInt2); (* becomes FALSE, because refInt2 is set to 0 *)
![]() | The implicit monitoring function Checkpointer acts on variables of the type |
Automatic pointer/reference update during Online Change
![]() | 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.
- Case 1: Symbol was determined
- If the symbol still exists in the new symbols that exist after the Online Change and if the type of the symbol has not changed, the pointer is moved to the symbol found. The pointer or address value is updated.
- If the symbol no longer exists in the new symbols or if the type of symbol has changed, the pointer is set to zero.
- Case 2: Symbol was not determined
- If a pointer refers to an address for which no symbol is found before the Online Change (e.g. because the pointer points to a memory area outside the PLC), the pointer value is not changed during the Online Change.
Requirements:
- This function requires the (ADS) symbol description of the variable to which the pointer points to. If there is no symbol description for a variable, e.g. due to the use of Attribute 'hide', the pointer is not taken into account.
- The pointer must point to a variable/object within the PLC memory. Pointers pointing to a memory area outside the PLC memory are not changed during Online Change.
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: