Martin Melka
Martin Melka

Reputation: 7799

How to declare a fixed value in a record?

I would like to know how do I declare a record, that has some fixed values. I need to send data using this pattern: Byte($FF)-Byte(0..250)-Byte(0..250). I am using record for that and I would like to have the first value of it constant, so that it can't be messed up. Such as:

TPacket = record
  InitByte: byte; // =255, constant
  FirstVal,
  SecondVal: byte;
end;

Upvotes: 7

Views: 6051

Answers (4)

Francesca
Francesca

Reputation: 21650

You can't rely on a constructor because, contrary to Classes, Records are not required to use them, the default parameterless constructor being used implicitly.

But you can use a constant field:

type
  TPacket = record
   type
     TBytish = 0..250;
   const
     InitByte : Byte = 255;
   var
     FirstVal,
     SecondVal: TBytish;
  end;

Then use this as a regular Record, except that you don't have (and you can't) change the InitByte field.
FillChar preserves the constant field and behaves as expected.

procedure TForm2.FormCreate(Sender: TObject);
var
  r: TPacket;
begin
  FillChar(r, SizeOf(r), #0);
  ShowMessage(Format('InitByte = %d, FirstVal = %d, SecondVal = %d', [r.InitByte, r.FirstVal,r.SecondVal]));
  // r.InitByte := 42;  // not allowed by compiler
  // r.FirstVal := 251; // not allowed by compiler
  r.FirstVal := 1;
  r.SecondVal := 2;
  ShowMessage(Format('InitByte = %d, FirstVal = %d, SecondVal = %d', [r.InitByte, r.FirstVal,r.SecondVal]));
end;

Updated to include the nested type range 0..250

Upvotes: 13

GJ.
GJ.

Reputation: 10937

This is the most simple way:

type
  TPacket = record
    InitByte: byte; // =255, constant
    FirstVal,
    SecondVal: byte;
  end;

var  
  Packet : TPacket = (InitByte: 255);

const
  Packet1 : TPacket = (InitByte: 255);

Upvotes: 0

Johan
Johan

Reputation: 76724

Given the fact that records can now have properties, you can define a record as:

TMixedFixed = record
strict private
  FFixed: byte;
  FVariable1: byte;
  FVariable2: byte;
public
  property Fixed read FFixed;
  property Variable read FVariable write FVariable;
  constructor Create(Var1, Var2: byte);
end; 

constructor TMixedFixed.create(Var1, Var2: byte);
begin
  FFixed:= 255;
  FVariable1:= Var1;
  FVariable2:= Var2;  
end;

Given the fact that the real variables are strict private you should not be able to touch them without special magic. You will have to use the constructor to init the 'fixed' values though.

Upvotes: 0

Mike W
Mike W

Reputation: 1284

Modern versions of Delphi allow record methods. While you can't prevent someone from changing the field you can at least initialize it properly:

type
  TPacket = record
    InitByte: byte; // =255, constant
    FirstVal,
    SecondVal: byte;
    constructor Create(val1, val2 : byte);
  end;


constructor TPacket.Create(val1, val2: byte);
begin
  InitByte := 255;
  FirstVal := val1;
  SecondVal := val2;
end;

Upvotes: 2

Related Questions