Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2006-10

more Variant thoughts (was: Variant record types in Sockates unit)

3 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Alexander Todorov

I made the simple test below:

program project1;
{$ifdef fpc}
   {$mode objfpc}{$H+}
{$endif}
{$apptype console}
type
  TTagVariant = record
     AlwaysThere : Integer;
     case Flag : Boolean of
       false: (false_1, false_2 : Byte);
       true : (true_1: Word);
  end;
var V : TTagVariant;
begin
  V.AlwaysThere := 1;
  V.Flag := false;
  V.true_1 := 200; // should compiler raise a run time error here
  V.false_1 := 100;
  writeln('V.Flag=', V.Flag, ', V.false_1=', V.false_1, ',
V.true_1=', V.true_1);
  V.Flag := true;
  V.true_1 := 200;
  V.false_1 := 100;// should compiler raise a run time error here
  writeln('V.Flag=', V.Flag, ', V.false_1=', V.false_1, ',
V.true_1=', V.true_1);
  writeln('Addresses: ', 'V.false_1=', Integer(@V.false_1), ',
V.true_1=', Integer(@V.true_1));
end.

The results are:
V.Flag=FALSE, V.false_1=100, V.true_1=100
V.Flag=TRUE, V.false_1=100, V.true_1=100
Addresses: V.false_1=134632390, V.true_1=134632390

What I am thinking about is:
1) If the Flag field is set to true and the programmer uses field from the variant part which is declared in the false section, should there be a run time error or not?
Although it will be slowly should the compiler check V.Flag and consider the other fields undefined? Something like "Inaccessible record field used" error?
2) In the test program the addresses of the two fields are the same due to the default aligning used by the compiler. That's why the output is the number 100.
In Delphi these addresses differ in 1 byte, so the ouput is : V.Flag=FALSE, V.false_1=100, V.true_1=200
V.Flag=TRUE, V.false_1=100, V.true_1=200
Is this by design or FPC has an inconsistency with Delphi?

3) Bug in Lazarus code complete. Does not show the Flag field of the variant. Delphi does.
I will fill a bug report.

Please someone with deeper knowledge on variant records and how the compiler handles them answer these questions.

Reply by email

Michael Van Canneyt
to Alexander Todorov
Alexander Todorov wrote 49 lines
I made the simple test below: program project1; {$ifdef fpc} {$mode objfpc}{$H+} {$endif} {$apptype console} type TTagVariant = record AlwaysThere : Integer; case Flag : Boolean of false: (false_1, false_2 : Byte); true : (true_1: Word); end; var V : TTagVariant; begin V.AlwaysThere := 1; V.Flag := false; V.true_1 := 200; // should compiler raise a run time error here V.false_1 := 100; writeln('V.Flag=', V.Flag, ', V.false_1=', V.false_1, ', V.true_1=', V.true_1); V.Flag := true; V.true_1 := 200; V.false_1 := 100;// should compiler raise a run time error here writeln('V.Flag=', V.Flag, ', V.false_1=', V.false_1, ', V.true_1=', V.true_1); writeln('Addresses: ', 'V.false_1=', Integer(@V.false_1), ', V.true_1=', Integer(@V.true_1)); end. The results are: V.Flag=FALSE, V.false_1=100, V.true_1=100 V.Flag=TRUE, V.false_1=100, V.true_1=100 Addresses: V.false_1=134632390, V.true_1=134632390 What I am thinking about is: 1) If the Flag field is set to true and the programmer uses field from the variant part which is declared in the false section, should there be a run time error or not?

No. No checking is performed on this.

Although it will be slowly should the compiler check V.Flag and consider the other fields undefined? Something like "Inaccessible record field used" error?

No.

The 'Flag' field is purely informational and has no restrictive meaning. It's a hint to the programmer, but nothing more.
This is how pascal is defined.

Michael.

Reply by email

Jonas Maebe
to Alexander Todorov: I made the simple test below: program project1; {$ifdef fpc} {$mode objfpc}{$H+} {$endif}…
Alexander Todorov wrote 7 lines
2) In the test program the addresses of the two fields are the same due to the default aligning used by the compiler. That's why the output is the number 100. In Delphi these addresses differ in 1 byte, so the ouput is : V.Flag=FALSE, V.false_1=100, V.true_1=200 V.Flag=TRUE, V.false_1=100, V.true_1=200 Is this by design or FPC has an inconsistency with Delphi?

Both. All components of the variant part of a record always start at the same address by design (because it avoids changing the overlapping of the variant fields depending on the packrecords setting), and apparently this is different in Delphi.

Jonas

Reply by email