- What does the "integer" and the constants do? Or they are just purely asthetics?
In a way the 'integer' part is aesthetic, but it can be practical. as well.
What if you would only have two different 'unions' ? Then you could use a boolean (true and false value). Taazz could just as well had used a byte value for his example (but he didn't
)
The used constants, well (in this case) they need to match the integer type and be unique for each variable part that you want to declare.
Would taazz have used this form:
TMyLongInt = record
case boolean of
true : (LongNo : LongInt);
false : (Bytes : Array [0..3] of Byte);
?? : (Words : Array [0..1] of Word);
?? : (Chars : Array [0..3] of Char);
end;
.. then the boolean identifier wouldn't offer enough different values to complete the structure, ergo he used a longint to make sure this structure can grow, and is future proof as it now offers more constants to be used in order to extend the structure even further (do try that yourself and see).
- What if the size of the variants are not the same? There will be common and uncommon bytes right?
Yes.
In fact you could for instance use the first byte in the record to define/recognize 255 different definitions of your record (or a word for even more).
You are _allowed_ to use common fields as taazz showed (those that actually make sense), but you could just as well make 255 completely different structures inside the record with using the first byte to determine it's structure programmatically.
For instance, make the char array 6 bytes instead of 4 as taazz showed. If you do a
WriteLn(sizeOf(TMyLongInt)) you'll notice that the record isn't 4 bytes anymore, but grows to being 6 bytes (or perhaps even 8/16 depending on the alignment of the record fields). In variable records, the record size becomes the size of the 'biggest' structure that is needed to store all the fields into memory.
I would really encourage you to play with simple things like WriteLn, to see what it actually does in practice.
One for the road
program variable_record;
Uses
SysUtils;
Type
TMyLongInt = record
case integer of
1 : (LongNo : LongInt);
2 : (Bytes : Array [0..3] of Byte);
3 : (Words : Array [0..1] of Word);
4 : (Chars : Array [0..3] of Char);
end;
Var
MyLongInt : TMyLongInt;
begin
{$IFDEF ENDIAN_LITTLE}
MyLongInt.LongNo := $6C6F6F43;
{$ELSE}
MyLongInt.LongNo := $436F6F6C;
{$ENDIF}
With MyLongInt do
begin
WriteLn('LongNo = #', LongNo , ' = $', IntToHex(LongNo , SizeOf(LongInt)));
WriteLn('Words[0] = #', Words[0], ' = $', IntToHex(Words[0], SizeOf(Word)));
WriteLn('Words[1] = #', Words[1], ' = $', IntToHex(Words[1], SizeOf(Word)));
WriteLn('Bytes[0] = #', Bytes[0], ' = $', IntToHex(Bytes[0], SizeOf(Byte)));
WriteLn('Bytes[1] = #', Bytes[1], ' = $', IntToHex(Bytes[1], SizeOf(Byte)));
WriteLn('Bytes[2] = #', Bytes[2], ' = $', IntToHex(Bytes[2], SizeOf(Byte)));
WriteLn('Bytes[3] = #', Bytes[3], ' = $', IntToHex(Bytes[3], SizeOf(Byte)));
Writeln('Chars = ', Chars);
end;
end.