On Sun, 2 Jul 2017, Martok wrote:
Hi all,
The only way to get data with an invalid value in an enum in Pascal is by
using an unchecked (aka explicit) typecast, by executing code without range
checking (assigning an enum from a larger parent enum type into a smaller
sub-enum type), or by having an uninitialised variable.
Turns out this is really not true. There are also as "esoteric" things as using
Read(File). Or TStream.Read. Or the socket implementation of your choice. Or by
calling a library function. There are many ways to have an invalid value in an
enum in any meaningful code. Pretty much everything that is not a direct
assignment from a constant is a potential candidate.
These cases are without exception covered by the " unchecked (aka explicit)
typecast,"
part of Jonas's statement. Including Read(File).
If you use Read(File) you are implicitly telling the compiler that the file
only contains valid values for the enum. If you yourself are not sure of this,
you must use file of integer instead.
If you check their definitions, you will see that they all use untyped
buffers to do their work. So all 'type safety' bets are off as soon as
you use one of these mechanisms. This is not only true of enums, but for
every data type.
The correct pascal way is to do
var
I : integer;
M : MyEnum;
begin
MyStream.ReadBuffer(I,SizeOf(I));
if (I>=Ord(Low(TMyEnum))) and (I<=Ord(High(TMyEnum))) then
M:=TMyEnum(I)
else
// error
end
Instead of
MyStream.ReadBuffer(M,SizeOf(M));
Which is inherently not safe, as it uses an untyped buffer.
In essence:
you are on your own as soon as you use external sources of values for enums.
Michael.
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel