Please don't put words in my mouth Michael or twist me up with word play.  I have never said I want to forbid the storing or communication of enumerations, and if people start using my argument for the exact opposite of what I'm trying to advocate and smugly say "I rest my case", then you can have my resignation. Please clarify with me before making such assumptions next time.

Because enumerations may take on an invalid value in these media (there's no real way you can eliminate this possibility), you need a reliable means to check their validity.  Many of FPC's optimisations assume that a variable of type TMyEnum is valid, so it skips range-checking for performance reasons among others, and instructions like "if Value < Low(TMyEnum) then" are always assumed to be False.  Sometimes even the typecasting gets shortcut so you have to be very careful.  I suggested one should not use enumerations as the only way to get around that, which is not ideal at all, but to use enumerations on top of Jonas' stance of essentially demanding undefined program behaviour for invalid values is just plain dangerous for real-world applications.

My original suggestion was to use an intrinsic like "if IsValidEnum(Value) then" as an efficient and robust way to check if the variable contains a valid value for the relevant enumeration, once which won't be shortcut by the compiler's assumptions as with case blocks and the if-statement in the last paragraph.  It was then brought to my attention that a variant had already been proposed with the "is" operator, which in my eyes is a little bit better because it doesn't introduce a new intrinsic that may clash with existing function names in some projects.

But to avoid a fight or anything of the sort, given that external data is read as an enumeration and may contain invalid data (which to give a concrete definition, is an integer value that doesn't map to any element in the enumeration), and it won't be caught by case blocks and can trigger an access violation if a jump table is employed (this is how the compiler currently behaves), what would you propose be the best solution?

Gareth aka. Kit


On 05/07/2019 01:52, Michael Van Canneyt wrote:


On Fri, 5 Jul 2019, J. Gareth Moreton wrote:

Ah, my apologies, Michael.

I can see the issue of it being a convenience thing, but given that many programmers have fallen foul of the lack of range checking in case blocks, the typecasting necessary to avoid the problem is cumbersome, adds a performance penalty and, ultimately, implies you should just not use enumerations at all in that instance.

With this sentence you forbid storing or communicating enumerated values in any way: file, database, over network. It can be used only in a computer program and never leave the context of the running program under any form. Because as soon as it is somehow communicated, there is a chance it becomes invalid in return
communication.

Additionally you must then also abolish typecasting to an enumerated (or
pointers to enumerated values), since that also can be a source of invalid
values for an enumerated.

Or are you realy advocating we write code such as

Case MyInteger of
  0 : MyEnum:=ValueOrd0
  1 : MyEnum:=ValueOrd2;
else
  someError
end;
etc, whenever an integer must be changed to an enumerated ?

IMHO you would reduce the usabilty of enumerateds to almost zero by doing
so.

So you may want to reconsider, since in my experience most enumerateds at
one point do end up outside the program and typecasts are equally
widespread.

These patterns are so ubiquitous it is worthy of an intrinsic.

Michael.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



---
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