Variable: VAR_IN_OUT Permalink

A ‎VAR_IN_OUT‎ variable is an input/output variable, which is part of a POU interface and serves as a formal pass-by-reference parameter.

Syntax

<keyword> <POU name>
VAR_IN_OUT
    <variable name> : <data type>;
END_VAR

<keyword> : FUNCTION | FUNCTION_BLOCK | METHOD | PRG

You can declare an input/output variable in the ‎VAR_IN_OUT‎ declaration section in the POUs ‎PRG‎, ‎FUNCTION_BLOCK‎, ‎METHOD‎ or ‎FUNCTION‎. The ‎VAR_IN_OUT‎ variable can be read and written.

Usage

  • Call: When a POU is called, the formal ‎VAR_IN_OUT‎ variable receives the actual variable ("pass-by-reference variable") as the argument. At runtime, no copies are generated when parameters are passed. Instead, the formal variable receives a reference to the actual variable passed remotely. The referential variables contain a memory address internally as a value to the actual value (pass as pointer, call-by reference). It is not possible to specify a constant (literal) or a bit variable directly as an argument.

  • Read/write access within the POU: If the variable is written to within the POU, then this affects the passed variable. When the POU is exited, any performed changes are retained. This means that a POU uses its ‎VAR_IN_OUT‎ variables just like the calling POU uses its variables. Read access is always permitted.

  • Read/write access remotely: ‎VAR_IN_OUT‎ variables cannot be directly read or written remotely via ‎<function block instance name>.<variable name>‎. This works only for ‎VAR_INPUT‎ and ‎VAR_OUTPUT‎ variables.

  • Passing string variables: If a string variable is passed as an argument, then the actual variable and the formal variable should have the same length. Otherwise the passed string can be manipulated unintentionally. This problem does not occur in the case of ‎VAR_OUTPUT CONSTANT‎ parameters.

  • Passing bit variables: A bit variable cannot be passed directly to a ‎VAR_IN_OUT‎ variable because it needs an intermediate variable.

  • Passing of properties: Not permitted

If a string is passed as a variable or a constant to a formal ‎VAR_IN_OUT CONSTANT‎ variable, then the string is automatically passed completely. You do not have to check the string length.

For more information, see: "VAR_IN_OUT CONSTANT" Transfer Variable

Example

Passing arrays

TYPE DUT_A :
STRUCT
        xA: BOOL;
        iB: INT;
END_STRUCT
END_TYPE

FUNCTION_BLOCK FB_SetArray
VAR_IN_OUT
        aData_A : ARRAY[0..1] OF DUT_A; // Formal variable
END_VAR
aData_A[0].xA := TRUE;
aData_A[0].iB := 100;

PROGRAM PLC_PRG
VAR
        fbSetA : FB_SetArray;
        aSpecialData : ARRAY[0..1] OF DUT_A; // Actual variable
END_VAR
fbSetA(aData_A := aSpecialData);
_cds_varinouts_array.png

Passing strings

{attribute 'qualified_only'}
VAR_GLOBAL
        g_sDEV_STATUS : STRING(25) := 'Device_A';
END_VAR

FUNCTION_BLOCK FB_SetStatus
VAR_IN_OUT
        sDeviceStatus : STRING(25); // Formal parameter
END_VAR
sDeviceStatus := CONCAT(sDeviceStatus, ' Activ');

PROGRAM PLC_PRG
VAR
        fbDoB : FB_SetStatus;
END_VAR
fbDoB(sDeviceStatus := GVL.g_sDEV_STATUS); //Call with actual parameter

The variable ‎sDeviceStatus‎ is part of the POU interface of ‎FB_B‎. When calling ‎fbDoB‎, first a device name is assigned to the string and then the string is manipulated.

_cds_varinouts_string.png

Passing bit variables

VAR_GLOBAL
        xBit0 AT %MX0.1 : BOOL;
        xTemp : BOOL;
END_VAR

FUNCTION_BLOCK FB_DoSomething
VAR_INPUT
        xIn : BOOL;
END_VAR
VAR_IN_OUT
        xInOut : BOOL;
END_VAR
IF xIn THEN
        xInOut := TRUE;
END_IF

PROGRAM PLC_PRG
VAR
        xIn : BOOL;
        DoSomething_1  : FB_DoSomething;
        DoSomething_2  : FB_DoSomething;
END_VAR

// The following line of code causes a compiler error:
// C0201: Typ 'BIT' is not equal to type 'BOOL' of VAR_IN_OUT 'xInOut'
DoSomething_1(xIn := xIn, xInOut := xBit0);

// Workaround
xTemp := xBit0;
DoSomething_2(xIn := xIn, xInOut := xTemp);
xBit0 := xTemp;

The program calls the function block instances ‎DoSomething_1‎ and ‎DoSomething_2‎. As a result of the direct assignment of the bit variable ‎xBit0‎ to the ‎VAR_IN_OUT‎ input, a compiler error is generated when the ‎DoSomething_1‎ instance is called. In contrast, calling the ‎DoSomething_2‎ instance with the assignment of an intermediate variable is correct code.