[fpc-devel] [Suggestion] Enumeration range-check intrinsic

J. Gareth Moreton gareth at moreton-family.com
Fri Jul 5 01:40:15 CEST 2019


Mucking around with pointers will always produce unpredictable code if 
you don't take care in what you're doing (and in your example, it uses 
tools that already exist), but Jonas, I have to protest your logic.  
Saying it's safer to refuse to do it at all instead of doing something 
that works part of the time is not always a sound design philosophy.  
Enums taking on invalid values is something that can and does happen, 
but by adamantly refusing to allow the programmer to check its validity 
and demanding unpredictable program behaviour is not something I or 
others can accept.  Or saying that all bets are off if a file is corrupt 
or has been tampered with... some programs, by design, are simply not 
allowed to crash.  If a sensor on an aircraft returned an invalid value 
(say for the sake of argument it was an undercarriage feedback that 
returned "Locked", "Stowed" and "Off" (stowed but without hydraulic 
pressure)) and the flight computer crashed because the developers were 
not allowed to create defined behaviour for invalid data, would that be 
acceptable for you?

There have been so many bug reports from all sorts of developers who 
have complained abut this behaviour and telling them that "it's not a 
bug" and not even offering them a workaround from undefined behaviour is 
both arrogant and ignorant.

When entirely self-contained within a program, the type system is fine, 
and there's no need to do range checks on enumerations, but when you 
have an external interface, such as a data file or a third-party library 
(either written in FPC or another language), there needs to be a way to 
check if the enum is within range or not, and using the "is" operator in 
this way is a perfectly reasonable way of doing things.  Because it's 
just an integer value at the lowest level, it will return a sane answer 
unless you go out of your way to try to break it.

As for the thing about keeping Pascal pure and consistent... it never 
was.  You have code blocks wrapped in "begin...end" and then you have 
the oddball that's "repeat...until", which is a carry-over from some 
dialects of BASIC.  And then you have things like the "class procedure 
Etc; static;" directive when a slightly better design might have been 
"static procedure Etc;", but it's too late to change that now.  
Sometimes you have to make design choices based on realistic needs 
rather than an ideal.

It can be enough to put in the documentation for 'case' something like 
the following, since it is these that cause crashes: "*WARNING:* Case 
blocks do not check to see if an enumerated value falls within the valid 
range, and passing an invalid value can trigger an access violation.  To 
avoid this behaviour when the validity of the input is uncertain, 
perform a separate check with "(Value is TEnum)" - a result of False 
indicates an invalid value." - that is all that would be needed.  If 
you're not happy with using "is" for this purpose, then I would like to 
offer my original option of an intrinsic that takes on the form of a 
Boolean function: "if IsValidEnum(Valid) then ...".  Note I do not 
consider trapping EAccessViolation to be an acceptable solution because 
it is very inefficient with performance and is too broad an exception 
that usually indicates a serious problem (e.g. insufficient system memory).

Ultimately, being forced to ditch enumerations for classic C-style 
constants defined against the Integer type (the only real workaround) 
only makes the code more difficult to understand, and a more junior 
developer may think to replace them with enumerations under the 
philosophy of improving readability, not realising that it will cause 
the compiler to shortcut the safety checks.  If I were a senior project 
developer, I simply could not take such a risk and would discard FPC 
completely for a tool what will not cause this problem (or has a 
documented workaround).

You could consider this an ultimatum, but I know it will be pointless to 
do that because you'll just ignore me.  So I'm pleading, Jonas... there 
needs to be a way to check if an enumeration contains an invalid value 
to avoid diving into the realm of undefined behaviour.  Just because you 
wouldn't use it doesn't mean we won't.

Gareth



---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20190705/1298d387/attachment.html>


More information about the fpc-devel mailing list