Sign in Join

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

Mailing lists / fpc-pascal / 2022-08

Union followed by Property does not compile !

4 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Skybuck Flying
program TestProgram3;

{

Test program to illustrate the 'union' followed by property problem in Delphi language and Free Pascal Language

version 0.01 created on 1 august 2022 by Skybuck Flying

There is a problem with "unions" in Delphi language:

When a property follows a "union" declaration it does not compile !

See
TDataExample1 which does compile (no property)
vs
TDataExample2 which does NOT compile (with property)

}

{$mode objfpc}{$H+}
uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  Classes, SysUtils, CustApp
  { you can add units after this };
type
  { TMyApplication }
  TMyApplication = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
    procedure WriteHelp; virtual;
  end;

{ TMyApplication }

type
      TDataExample1 = record
            mField : integer;
            // UNION example
            case integer of
                  0 : ( mData : int64 );
                  1 : ( mByte : packed array[0..7] of byte );
            // DOES COMPILE
      end;
      TDataExample2 = record
            mField : integer;
            // UNION example
            case integer of
                  0 : ( mData : int64 );
                  1 : ( mByte : packed array[0..7] of byte );
            // !!! DOES NOT COMPILE, PROBLEM !!!
            property Field : integer read mField write mField;
      end;
procedure TMyApplication.DoRun;
var
  ErrorMsg: String;
begin
  // quick check parameters
  ErrorMsg:=CheckOptions('h', 'help');
  if ErrorMsg'' then begin
    ShowException(Exception.Create(ErrorMsg));
    Terminate;
    Exit;
  end;
  // parse parameters
  if HasOption('h', 'help') then begin
    WriteHelp;
    Terminate;
    Exit;
  end;
  { add your program here }
  // stop program loop
  Terminate;
end;
constructor TMyApplication.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  StopOnException:=True;
end;
destructor TMyApplication.Destroy;
begin
  inherited Destroy;
end;
procedure TMyApplication.WriteHelp;
begin
  { add your help code here }
  writeln('Usage: ', ExeName, ' -h');
end;
var
  Application: TMyApplication;
begin
  Application:=TMyApplication.Create(nil);
  Application.Title:='My Application';
  Application.Run;
  Application.Free;
end.
Michael Van Canneyt
to Skybuck Flying
Skybuck Flying wrote
} {$mode objfpc}{$H+}

You need additionally a modeswitch for advanced records, or properties in records will not work:

{$modeswitch advancedrecords}
Show quoted text 20 lines
            // UNION example             case integer of                   0 : ( mData : int64 );                   1 : ( mByte : packed array[0..7] of byte );             // DOES COMPILE       end;       TDataExample2 = record            mField : integer;             // UNION example             case integer of                   0 : ( mData : int64 );                   1 : ( mByte : packed array[0..7] of byte );             // !!! DOES NOT COMPILE, PROBLEM !!!             property Field : integer read mField write mField;       end;

The variant part of a record must always come last. The property should be moved to before the 'case' :

TDataExample2 = record
   mField : integer;
   property Field : integer read mField write mField;
   case integer of
   0 : ( mData : int64 );
   1 : ( mByte : packed array[0..7] of byte );
end;

This compiles when I tried.

Michael.

Unknown author
to Michael Van Canneyt
Michael Van Canneyt wrote
The variant part of a record must always come last.

FWIW: is this documented somewhere easily found?

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list where it belongs!*
Martin Frb
to Unknown author
wkitty42--- wrote 5 lines
On 8/2/22 5:12 AM, Michael Van Canneyt via fpc-pascal wrote: > The variant part of a record must always come last. FWIW: is this documented somewhere easily found?

google
free pascal language reference

https://www.freepascal.org/docs-html/ref/ref.html

and read up on "record"

Show quoted text 8 lines
The variant part must be last in the record. The optional identifier in the case statement serves to access the tag field value, which otherwise would be invisible to the programmer. It can be used to see which variant is active at a certain time^3 <https://www.freepascal.org/docs-html/ref/refsu15.html#fn3x4>. In effect, it introduces a new field in the record.