REFERENCE

A REFERENCE is an "alias" for an object. You can write or read an alias using identifiers. The REFERENCE data type is comparable to the POINTER data type, but REFERENCE has the following advantages over POINTER:

Syntax: <Identifier>: REFERENCE TO <data type>

Sample declaration:

refInt  : REFERENCE TO INT;
nA      : INT;
nB      : INT;

You can now use refInt as "alias" for variables of type INT.

Assignment:

The address of the reference must be set via a separate assignment operation using the REFERENCE. 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);

You can check whether a reference points to a valid value (e.g. not equal to 0) using a special operator (see REFERENCE).

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 initialisation of the reference
REFERENCE 1:

References cannot be declared in the following way:

- REFERENCE TO REFERENCE
- ARRAY OF REFERENCE
- POINTER TO REFERENCE

Furthermore, you cannot declare a reference on a bit variable.

REFERENCE 2:

TwinCAT initializes references (with 0).

REFERENCE 3:

If a reference to an allocated input variable is used, the access (e.g. ref REF= input;) is interpreted as write access. This is not possible and leads to a compiler error during code generation.

Allocation operator REF=

The operator creates a reference (pointer) to a value.

Syntax:

<Variable1> REF= <Variable2>

Beispiel:

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)

Checking for valid references

You can use the operator __ISVALIDREF to check whether a reference points to a valid value, that is a value other than 0.

Syntax:

<Boolean variable> : = __ISVALIDREF (<with REFERENCE TO <datatype> declared identifier);

<Boolean variable> becomes TRUE if the reference points to a valid value, otherwise FALSE.

Example:

Declaration:

nVar : INT;
refInt : REFERENCE TO INT;
refInt0: REFERENCE TO INT;
bTestref : BOOL := FALSE;
bTestref0 : BOOL := FALSE;

Implementation:

nVar := nVar + 1;
refInt REF= nVar;
refInt0 REF= 0;
bTestref := __ISVALIDREF(refInt); (* becomes TRUE, because refInt points to nVar, which is non-zero *)
bTestref0 := __ISVALIDREF(refInt0); (* becomes FALSE, because refInt is set to 0 *)
REFERENCE 4:

The implicit CheckPointer monitoring function affects variables of type REFERENCE in the same way as pointer variables.

See also: