Delphi doesn't directly support any range checking or out-of-range excption raising for typecasts of integers to an enumeration. See: How do I convert an integer to an enumerated type? I am trying to get around this by automatic range checking of an array indexed on the enumeration sub-range. In my test program I deliberately used a non-continuous enumeration, which disables RTTI and provides a test for valid sub-range values that don't have a named enumeration but can be accessed by typecasting, Inc, Dec etc.
The program handles the non-enumerated element of the sub-range (2) as expected, but does not generate an out-of-range exception for the enumerated array - but does for the equivalent integer index array. Is there any good reason for this? I can work around by using the integer indexed array, but the enumeration index would be a bit more robust.
type MyEnum = (zero,one,three=3);
var EnumCheck: array[MyEnum] of integer = (0,1,2,3);
var iEnum: integer;
var MyEnumVar: MyEnum;
var IntArray: array[0..3] of integer = (0,1,2,3);
procedure Test;
begin
{$R+}
MyEnumVar:= MyEnum (1); // One
iEnum := EnumCheck[MyEnumVar]; // OK - iEnum = 1
MyEnumVar:= MyEnum (2); // Out-of-bound
iEnum := EnumCheck[MyEnumVar]; // OK - iEnum = 2
MyEnumVar:= MyEnum (3); // Three
iEnum := EnumCheck[MyEnumVar]; // OK - iEnum = 3
MyEnumVar:= MyEnum (4); // Out-of-bound
iEnum := EnumCheck[MyEnumVar]; // no Exception; iEnum is set to random value
iEnum := 4;
iEnum := IntArray[iEnum]; // Exception thrown here
iEnum := IntArray[4]; // Compiler "subrange" error
end;
Using Delphi 10.4 update 2
EDIT: I found my work around. Define the check array as:
var iCheck: array[Ord(Low(MyEnum))..Ord(High(MyEnum))] of integer = (0,1,2,3);
and an out-of-range exception is thrown as expected.