[fpc-devel] Dangerous optimization in CASE..OF

lazarus at kluug.net lazarus at kluug.net
Sat Jul 15 20:52:32 CEST 2017


Am Sa., Jul. 15, 2017 12:45 schrieb Jonas Maebe :
Classes are explicitly documented to initialise their contents with 
zero
Excuse me, but you have a collision in the way you think :)
On one hand, you try to be very fundamental about enums - you say that only declared enum values are valid. And there is no zero value for TMyEnum. TMyEnum is declared as follows:
TMyEnum = (one = 1, two);
TMyEnum is not a number so it cannot be initialized to zero. Because there is no zero. There are only two values, "one" and "two". I don't care about the bit pattern of the enum value - this is an implementation detail for me (that could change in the future just the same as the CASE statement changed).
On the other hand you say, it is documented to be declared to zero. So you say that an enumeration is an integer value with aliases for number values.
Well, you have 2 ways of solving this:
1.) HIGH-LEVEL enumeration: You say that an enumeration can have a value from a strict set of identifiers. In this case, you have to handle it like this in all cases:
1a) EnumValue := TEnum(IntegerValue) has to assign an always valid value to EnumValue (without range checking) or has to raise a range check error  (with range checking) if IntegerValue is not allowed in TEnum. It should be the same like when you assign an Int64 value to Integer field - you always get a valid integer (without range cheching) !!!
1b) You have to initialize EnumValue in objects to valid values, whatever the bit pattern is (bit pattern is not  in high-level enumerations).
1c) Inc/Dec has to increase/decrease the enum values and not ordinal values:
TEnum = (zero, two=2);
MyEnum := zero;
Inc(MyEnum); -> has to increase MyEnum to two, not 1.
1d) In this case you can leave the CASE optimization as it is.
- OR -
2.) LOW-LEVEL enumeration: You say that an enumeration is an ordinal type with enumeration values being only aliases for underlying ordinal values. An enumeration can have any possible value that is allowed by the ordinal type (Byte, Word, whatever).
=> 1a) + 1b) + 1c) + 1d) are not valid any more.
-----
Conclusion: you did only 1d - so you have done only 1 point from 4 (I may have forgotten some). All in all, the HIGH-LEVEL enumeration approach cannot be used in Pascal at all (you cannot fix 1a-1c) - because of code speed and/or compatibility reasons.
So, IMO the HIGH-LEVEL enum approach is wrong along with the CASE optimization.
I understand what you say about validity of enum values - but you did only the CASE optimization, not other steps that are from the same pot (1a-1c). If you want to leave the CASE optimization, you have to fundamentally change the enum type and fix 1a-1c.
That is also why we warn when you use a local ansistring variable 
without initialising it first: even though it won't crash your program 
(due to underlying needs by the reference counting mechanism), it is 
still a logic error.

Local variables are off-topic.
Ondrej
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20170715/aa53d746/attachment.html>


More information about the fpc-devel mailing list