Sign in Join

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

Mailing lists / fpc-pascal / 2022-08

Union field after property violates "field before property" rule + property of union field not possible.

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Skybuck Flying

Delphi and presumably Free Pascal has some language inconsistency and problem/short coming concerning "Union Field" and/or "Union Property":

The (previous) presented solution (included at end of post) is inconsistent in two ways:

1. Property of union not possible.

2. Order of field and property violations "field before property" rule.

(Both problems demonstrated in TDataExample3)

{

version 0.03 created on 14 august 2022 by Skybuck Flying:

Today I remember the rule which this union field is conflicting with.

The rule: "field before property"

Going to demonstrate it below

There are apperently two problems with this solution:

1. Property of union not possible ?!?

2. Inconsistent language design in respect to standard field + property relation (order of appearance/declaration)

// ERROR "field definition not allowed after methods or properties" problem 2.

}

type
      TDataExample3 = record
//          mStandardField : integer;  // OK
            // normal/standard property
            property StandardField : integer read mStandardField write mStandardField;
            mStandardField : integer;  // ERROR "field definition not allowed after methods or properties" problem 2.
            // union property
//          property UnionField : int64 read mData write mData;  // not possible, problem 1
            // union fields
            case integer of   // INCONSISTENT problem 2
                  0 : ( mData : int64 );
                  1 : ( mByte : packed array[0..7] of byte );
//          property UnionField : int64 read mData write mData;  // not possible, problem 1
      end;

The original problem was:

(*
      // ORIGINAL PROBLEM:
      TDataExample0 = record
      private
            mField : integer;
      public
            // UNION example
            case integer of
                  0 : ( mData : int64 );
                  1 : ( mByte : packed array[0..7] of byte );
            property Field read mField write mField; // DOES NOT COMPILE.
      end;
*)

      // UNION DECLARATION example that does work without properties, just to check"

      TDataExample1 = record
      private
            mField : integer;

      public
            // UNION example
            case integer of
                  0 : ( mData : int64 );
                  1 : ( mByte : packed array[0..7] of byte );
            // DOES COMPILE
      end;

Presented solution for union field in record with properties was:

      TDataExample2 = record
      private
            mField : integer;

      public
            // SOLUTION:
            property Field : integer read mField write mField;

            // PUT CASE STATEMENT LAST
            case integer of
                  0 : ( mData : int64 );
                  1 : ( mByte : packed array[0..7] of byte );
      end;

Bye,
Skybuck.

Reply by email

Jean SUZINEAU
to Skybuck Flying

For this particular error I think you should just follow the advice of compiler in the error message :

Le 14/08/2022 à 11:49, Skybuck Flying via fpc-pascal a écrit :

Show quoted text 6 lines
            // normal/standard property             property StandardField : integer read mStandardField write mStandardField;             mStandardField : integer;  // ERROR "field definition not allowed after methods or properties" problem 2.

Error: Fields cannot appear after a method or property definition, start a new visibility section first

   property StandardField : integer read mStandardField write
mStandardField;
public
 mStandardField : integer;

But I think you'll get then, on the property line : Error: Unknown class field or method identifier "mStandardField"

Reply by email

Jean SUZINEAU
to Jean SUZINEAU

May the solution to your problem should be just :

 TDataExample
 =
  record
    case integer
    of
      0: (mData: Int64);
      1: (mByte: packed array[0..7] of Byte);       2: (UnionField: Int64);
  end;

?

You aren't going to define a getter or setter method on your property, just an "alias" to mData ?

Reply by email

Jean SUZINEAU
to Jean SUZINEAU

An if you eventually need a read only UnionField :

 TmByte= packed array[0..7] of Byte;
 TDataExample2
 =
  record
    internal
    :
     record
       case integer
       of
         0: (mData: Int64);
         1: (mByte: TmByte);
     end;
   property mByte     : TmByte read internal.mByte;    property UnionField: Int64  read internal.mData;   end;

Reply by email