[fpc-pascal] Case in Record

Frank Peelo f26p at eircom.net
Tue Oct 6 17:31:09 CEST 2009


On 06/10/2009 15:00, Felipe Monteiro de Carvalho wrote:
> On Tue, Oct 6, 2009 at 10:13 AM, 章宏九 <secludedsage at gmail.com> wrote:
> 
>>Type
>> MyRec = Record
>>         X : Longint;
>>         Case byte of
>>           2 : (Y : Longint;
>>                case byte of
>>                3 : (Z : Longint);
>>                );
>>         end;
> 
> 
> I think the cases are useless here. AFAIK the case inside record is
> utilized to give multiple options of use for the same memory area.


Yup. Like you say, this is a wierd example.

It's called a "variant record". Google for that term.
http://www.delphicorner.f9.co.uk/articles/op6.htm
That means, a record structure where one or more fields occupy the same 
memory, but have different types. Like a union in C. So depending on 
which field you read, the memory area can be read in different types.

So if you have
Type
   MyRec = Record
     Case byte of
     1: (X : Integer;);
     2: (Y : Word;);
   end;
var
   v : MyRec;

Begin
   v.y := 65535;
   writeln(v.x);
end.

assigning 65535 to v.y sets the underlying bytes to $FF, $FF so v.X is -1.

Now, one would not normally do this (writing to one field and reading 
the other). If you write to one field, the memory under the other one(s) 
is messed up. So you should only read from the field that you write to.

How do you know which field to read from?

Normally, you would have a tag field. This is a field with a specific 
ordinal type coming before the variant fields.

Type
   MyRec = Record
     Case FieldType:byte of
     1: (X : Integer;);
     2: (Y : Word;);
   end;

Now, if you are writing to field X, you should write a 1 to FieldType. 
Elsewhere in your program, you can read FieldType, and if it is 1 you 
read x. If it is 2 you read y. And if it is some other value you output 
an error message...

I think the syntax with just a type and no tag field name (case byte of) 
was invented afterwards, to handle the case when you don't want a tag field.

...

>>And the wiki said that Object is not used very
>>much. Does this mean that Object is deprecated?
> 
> 
> Deprecated means that the feature will or may be removed in the
> future, but AFAIK there are no plans to remove support for Object. So
> I would say it's a legacy feature (from Turbo Pascal), but not
> deprecated at the moment.

Object was introduced in the first object-oriented Borland Pascal, 
TurboPascal 5.5. To use polymorphism, you access objects through a 
pointer (because if you say var o:tMyObject; then you *know* what type 
it is). When Delphi came along, seems Borland decided that everyone 
should *always* use pointers for object types, and introduced the Class, 
which is always on the heap and handled as a pointer. Any new concepts 
that were introduced, like properties, were applied only to the new 
classes and objects were left in a corner, like the embarrassing 
relative that you wish you could get rid of, but can't. IMHO objects are 
the less confusing of the two, but they seem to be, not quite 
deprecated, but discouraged. So as Felipe said:

> If you are not sure which one to use, then just use classes.
> 

FP




More information about the fpc-pascal mailing list