Sign in Join

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

Mailing lists / fpc-pascal / 2020-10

Are record fields zeroed on declaration of a record?

11 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Bo Berglund

I would like to know if data containers of type packed record are zeroed when the item is declared?

type
  TMyRecord = packed record
    AField1: byte;
    AField2: word;
    AField3: single;
    AField4: boolean;
    AField5: array[0..15] of Cardinal;
  end;
procedure SomeProc;
var
  myRec: TMyRecord;
begin
 ...

Will random data fill myRec until I assign each field or will the entire record be zeroed at this point?

Bo Berglund Developer in Sweden

Reply by email

Michael Van Canneyt
to Bo Berglund
Bo Berglund wrote 20 lines
I would like to know if data containers of type packed record are zeroed when the item is declared? type TMyRecord = packed record AField1: byte; AField2: word; AField3: single; AField4: boolean; AField5: array[0..15] of Cardinal; end; procedure SomeProc; var myRec: TMyRecord; begin ... Will random data fill myRec until I assign each field or will the entire record be zeroed at this point?

No, as with all local unmanaged variables it contains random data. The best you can do is add this as the first line:

begin
   MyRec:=Default(TMyRecord);

It will in effect zero out the record.

Michael.

Reply by email

Bo Berglund
to Michael Van Canneyt

On Thu, 8 Oct 2020 10:47:52 +0200 (CEST), Michael Van Canneyt via fpc-pascal

Show quoted text 33 lines
On Thu, 8 Oct 2020, Bo Berglund via fpc-pascal wrote: > I would like to know if data containers of type packed record are > zeroed when the item is declared? > > type > TMyRecord = packed record > AField1: byte; > AField2: word; > AField3: single; > AField4: boolean; > AField5: array[0..15] of Cardinal; > end; > > procedure SomeProc; > var > myRec: TMyRecord; > begin > ... > > Will random data fill myRec until I assign each field or will the > entire record be zeroed at this point? No, as with all local unmanaged variables it contains random data. The best you can do is add this as the first line: begin MyRec:=Default(TMyRecord); It will in effect zero out the record.

OK,
is it possible to define the TMyRecord with default values so that when I do Default(TMyRecord) it will be non-zero defaults written instead of zeros?

Bo Berglund Developer in Sweden

Reply by email

Michael Van Canneyt
to Bo Berglund
Bo Berglund wrote 42 lines
On Thu, 8 Oct 2020 10:47:52 +0200 (CEST), Michael Van Canneyt via fpc-pascal wrote: > > > On Thu, 8 Oct 2020, Bo Berglund via fpc-pascal wrote: > >> I would like to know if data containers of type packed record are >> zeroed when the item is declared? >> >> type >> TMyRecord = packed record >> AField1: byte; >> AField2: word; >> AField3: single; >> AField4: boolean; >> AField5: array[0..15] of Cardinal; >> end; >> >> procedure SomeProc; >> var >> myRec: TMyRecord; >> begin >> ... >> >> Will random data fill myRec until I assign each field or will the >> entire record be zeroed at this point? > > No, as with all local unmanaged variables it contains random data. > The best you can do is add this as the first line: > > begin > MyRec:=Default(TMyRecord); > > It will in effect zero out the record. > OK, is it possible to define the TMyRecord with default values so that when I do Default(TMyRecord) it will be non-zero defaults written instead of zeros?

No. You will always need code for that.

Michael.

Reply by email

gabor
to Bo Berglund: On Thu, 8 Oct 2020 10:47:52 +0200 (CEST), Michael Van Canneyt via fpc-pascal is it…
OK, is it possible to define the TMyRecord with default values so that when I do Default(TMyRecord) it will be non-zero defaults written instead of zeros?

You can define typed constant and assign it to variable.

type
   TMyRecord = record
     X, Y: Integer;
     S: String;
   end;
const
   MYDEFREC: TMyRecord = (X: 1; Y: 2; S: 'ABC');
var
   R: TMyRecord;
begin
   R := MYDEFREC;
end.

Reply by email

Bo Berglund
to Michael Van Canneyt: No. You will always need code for that. Michael.

On Thu, 8 Oct 2020 13:04:43 +0200 (CEST), Michael Van Canneyt via fpc-pascal

Show quoted text 6 lines
> OK, > is it possible to define the TMyRecord with default values so that > when I do Default(TMyRecord) it will be non-zero defaults written > instead of zeros? No. You will always need code for that.

OK,
I have now added code that sets those fields that should have non-zero values to the default on startup. All others are handled by the Default() call.
Works fine.
Thank you for your clarification!

Bo Berglund Developer in Sweden

Reply by email

Ryan Joseph
to gabor: You can define typed constant and assign it to variable. type TMyRecord = record X, Y:…
Show quoted text 12 lines
On Oct 8, 2020, at 5:14 AM, gabor via fpc-pascal wrote: You can define typed constant and assign it to variable. type TMyRecord = record X, Y: Integer; S: String; end; const MYDEFREC: TMyRecord = (X: 1; Y: 2; S: 'ABC');

I never understood why we can't initialize fields at init time for records. Pascal seems to be the only language that doesn't support this in 2020. Thinking of C++, C#, PHP, Swift and many more all let you do this. Not even Delphi supports this AKAIK.

type
 TMyRecord = record
   X, Y: Integer = 0;
   S: String = '';
 end;

Regards,
Ryan Joseph

Reply by email

Michael Van Canneyt
to Ryan Joseph
Ryan Joseph wrote 19 lines
> On Oct 8, 2020, at 5:14 AM, gabor via fpc-pascal wrote: > > You can define typed constant and assign it to variable. > > type > TMyRecord = record > X, Y: Integer; > S: String; > end; > > const > MYDEFREC: TMyRecord = (X: 1; Y: 2; S: 'ABC'); I never understood why we can't initialize fields at init time for records. Pascal seems to be the only language that doesn't support this in 2020. Thinking of C++, C#, PHP, Swift and many more all let you do this. Not even Delphi supports this AKAIK.

Of course you can:

var
   x : record a,b : integer; end = (a:1;b:3);
begin
end.

This is identical to how C++ does it. From cppreference.com:

typedef struct { int k; int l; int a[2]; } T;
T x = {.l = 43, .k = 42, .a[1] = 19, .a[0] = 18 };

Michael.

Reply by email

Bo Berglund
to Michael Van Canneyt

On Thu, 8 Oct 2020 23:00:32 +0200 (CEST), Michael Van Canneyt via fpc-pascal

Show quoted text 38 lines
On Thu, 8 Oct 2020, Ryan Joseph via fpc-pascal wrote: > > >> On Oct 8, 2020, at 5:14 AM, gabor via fpc-pascal wrote: >> >> You can define typed constant and assign it to variable. >> >> type >> TMyRecord = record >> X, Y: Integer; >> S: String; >> end; >> >> const >> MYDEFREC: TMyRecord = (X: 1; Y: 2; S: 'ABC'); > > I never understood why we can't initialize fields at init time for > records. Pascal seems to be the only language that doesn't support this > in 2020. Thinking of C++, C#, PHP, Swift and many more all let you do > this. Not even Delphi supports this AKAIK. Of course you can: var x : record a,b : integer; end = (a:1;b:3); begin end. This is identical to how C++ does it. From cppreference.com: typedef struct { int k; int l; int a[2]; } T; T x = {.l = 43, .k = 42, .a[1] = 19, .a[0] = 18 };

If you do that can you be selective and initialize only some fields or must you list all or none?

Like:

type
  TmyRec = record
    a, b, c: integer;
    d, e: double
  end = (a:2; b:3; e:3.1415);
var
  charlie: TmyRec;
begin
  Default(charlie);

What will charlie.c and charlie.d contain now?
And are a, b and e left alone at the default values?

Or are all zero?

Bo Berglund Developer in Sweden

Reply by email

Michael Van Canneyt
to Bo Berglund
Bo Berglund wrote 45 lines
On Thu, 8 Oct 2020 23:00:32 +0200 (CEST), Michael Van Canneyt via fpc-pascal wrote: > > > On Thu, 8 Oct 2020, Ryan Joseph via fpc-pascal wrote: > >> >> >>> On Oct 8, 2020, at 5:14 AM, gabor via fpc-pascal wrote: >>> >>> You can define typed constant and assign it to variable. >>> >>> type >>> TMyRecord = record >>> X, Y: Integer; >>> S: String; >>> end; >>> >>> const >>> MYDEFREC: TMyRecord = (X: 1; Y: 2; S: 'ABC'); >> >> I never understood why we can't initialize fields at init time for >> records. Pascal seems to be the only language that doesn't support this >> in 2020. Thinking of C++, C#, PHP, Swift and many more all let you do >> this. Not even Delphi supports this AKAIK. > > Of course you can: > > var > x : record a,b : integer; end = (a:1;b:3); > > > begin > end. > > This is identical to how C++ does it. From cppreference.com: > > typedef struct { int k; int l; int a[2]; } T; > T x = {.l = 43, .k = 42, .a[1] = 19, .a[0] = 18 }; > If you do that can you be selective and initialize only some fields or must you list all or none?

You can do selected fields.
Fields you didn't specify are undefined.

But the code you posted is wrong.

Michael.

Reply by email

Ryan Joseph
to Bo Berglund: On Thu, 8 Oct 2020 10:47:52 +0200 (CEST), Michael Van Canneyt via fpc-pascal is it…
Show quoted text 6 lines
On Oct 8, 2020, at 4:58 AM, Bo Berglund via fpc-pascal wrote: OK, is it possible to define the TMyRecord with default values so that when I do Default(TMyRecord) it will be non-zero defaults written instead of zeros?

You need to make a method for tha. You can't even use constructors because they must have parameters for some reason but you can use a static class function (this requires advanced records mode switch of course). There is also an initialize operator that is in 3.2.0 I believe.

Sven did say one time that he MAY consider allowing a record initialization syntax inside code blocks (see below). That would be a nice option but they require all fields to be initialized. Having default values like C++ would be best though.

type
 TmyRec = record
   a, b, c: integer;
   d, e: double;
   class function Create: TMyRec; static;  // this syntax works.
   class operator Initialize(var self: TMyRec); // init operator gets called when the record is declared
 end;
var
 charlie: TmyRec = (a:2; b:3; e:3.1415);
begin
 charlie := TmyRec(a:2; b:3; e:3.1415); // this would be a nice addition to avoid constructors

Regards,
Ryan Joseph

Reply by email