Hi everyone,

So there have been a lot of issues going back and forth regarding case blocks when dealing with enumerations and what happens if the enum falls outside the valid range of values for some reason, because the internal domain check is sometimes omitted for performance reasons, since the value /shouldn't/ be invalid.  Thus, if it is invalid and a jump table is used, an access violation is raised.

Ultimately, the range check will likely not be included to safeguard against this, but there are still situations where an enumeration will take on an out-of-range value, like if it reads it from an external data file that is corrupted or of an incompatible version for the program.  So I would like to suggest a new intrinsic called InRange() or IsDomainValid() or something to that effect that takes an ordinal-type parameter and returns True if it contains a valid value for the enumeration (always True if it's a Byte or Word etc) and False if it is outside the valid domain, hence fulfilling the range check if it's something you really need.

The reason why I ask for an intrinsic instead of something like "if (Value >= Low(TEnumType)) and (Value <= High(TEnumType))" is because such code may be optimised out due to it logically being impossible for Value to be less than Low(TEnumType), for example, so it's harder than you think to check if the variable is in range.  Additionally, by having a generic intrinsic, it can generate more optimised code (e.g. the equivalent of "if (Value - Low(TEnumType)) < (High(TEnumType) - Low(TEnumType))", taking advantage of unsigned overflow if Value is less than the lower bound) and also to check for invalid values that fall within the maximum range (e.g. if you have something like "type TEnumType = (etZero, etOne, etSpecial = $FF);" and your Value holds the equivalent of $FE).

What are your thoughts? Would this be a decent compromise to fix the case range-check issue that keeps cropping up occasionally? I know it's causing some people to choose not migrate away from Delphi, and that is never really a good thing.  It should be easy enough to document as well, putting in an explicit warning for case to say that if the enumeration is out of range, it may cause a crash, and to prevent it, use the intrinsic to check beforehand.

Gareth aka. Kit



---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to