A subrange type is a user-defined type whose range of values is only a subset of that of the basic data type. You can also use implicit range boundary checks.
You can do the declaration in a DUT object but you can also declare a variable directly with a subrange type.
Syntax for the declaration as a DUT object:
TYPE <name>: <Inttype> (<ug>..<og>) END_TYPE;
|
a valid IEC identifier |
|
one of the data types SINT, USINT, INT, UINT, DINT, UDINT, BYTE, WORD, DWORD (LINT, ULINT, LWORD) |
|
a constant compatible with the basic type, setting the lower boundary of the range types The lower boundary itself is included in this range. |
|
a constant compatible with the basic type, setting the upper boundary of the range types. The upper boundary itself is included in this basic type. |
VAR
i : INT (-4095..4095);
ui : UINT (0..10000);
END_VAR
If a value is assigned to a subrange type (in the declaration or in the implementation) but does not match this range (for example, i:=5000
in the upper shown declaration example), a message will be issued.
In order to observe the range bounds of subrange types during runtime, the functions CheckRangeSigned
, CheckLRangeSigned
or CheckRangeUnsigned
, CheckLRangeUnsigned
have to be added to the application. For information on inserting the function, refer to the description of the function.
The purpose of this check function is the proper treatment of violations of the subrange (for example, by setting an error flag or changing the value). The function is called implicitly as soon as a variable of subrange type is assigned.
WARNING | |
---|---|
The assignment of a variable belonging to a signed subrange type entails an implicit call to CheckRangeSigned
. The default implementation of that function trimming a value to the permissible range is provided as follows:
Declaration part:
// Implicitly generated code : DO NOT EDIT
FUNCTION CheckRangeSigned : DINT
VAR_INPUT
value, lower, upper: DINT;
END_VAR
Implementation part:
// Implicitly generated code : Only an Implementation suggestion
IF (value < lower) THEN
CheckRangeSigned := lower;
ELSIF(value > upper) THEN
CheckRangeSigned := upper;
ELSE
CheckRangeSigned := value;
END_IF
When called, the function gets the following input parameters:
value
: the value to be assigned to the range type
lower
: the lower boundary of the range
upper
: the upper boundary of the range
As long as the assigned value is within the valid range, it will be used as return value of the function. Otherwise, in correspondence to the range violation, either the upper or the lower boundary of the range will be returned.
The assignment i:=10*y
will now be replaced implicitly by
i := CheckRangeSigned(10*y, -4095, 4095);
If y
, for example, has the value 1000
, the variable i
will not be assigned to 10*1000=10000 (as provided by the original implementation), but to the upper boundary of the range that is 4095.
The same applies to function CheckRangeUnsigned
.