Recent

Author Topic: Copy of record  (Read 8263 times)

Tommi

  • Full Member
  • ***
  • Posts: 213
Copy of record
« on: September 20, 2017, 07:33:07 pm »
On the internet I find that I cannot copy a record to another using := operator. I should use copyMem or similar or copy field by field.

But I see that simply using a:=b;  works nice. Every field of a is perfectly copied in b.

So what are the collateral effects if I do so ?

Thank you

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Copy of record
« Reply #1 on: September 20, 2017, 08:25:21 pm »
On the internet I find that I cannot copy a record to another using := operator. I should use copyMem or similar or copy field by field.

But I see that simply using a:=b;  works nice. Every field of a is perfectly copied in b.

So what are the collateral effects if I do so ?

Thank you
where on the internet? a Record is a static construct and as such the code to copy its contents can be calculated at compile time. this is the main way of copying one record to an other from the turbo pascal days long before dos and my time. Can you link the documentation that said that it might need updating.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Copy of record
« Reply #2 on: September 20, 2017, 08:28:47 pm »
Pascal record copying is so straightforward, and the basic result is exactly what you would expect for simple-type-fields. Class instances are copied such that published properties and events are also copied, without you having to write anything beyond a simple assignment operator.

Try the following. On the main form of a new Lazarus project drop a memo control. Set its Align to alClient. Add an OnCreate handler, and type definitions as follows, and see what the memo shows you of the copied records values:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$ModeSwitch advancedrecords}
  5.  
  6. interface
  7.  
  8. uses
  9.   SysUtils, Forms, Controls, StdCtrls;
  10.  
  11. type
  12.  
  13.   TMainForm = class(TForm)
  14.     Memo1: TMemo;
  15.     procedure FormCreate(Sender: TObject);
  16.   end;
  17.  
  18.   TRec = record
  19.     num  : Integer;
  20.     st   : String;
  21.     real : Double;
  22.     align: TAlign;
  23.     form : TMainForm;
  24.     procedure Init(aNum: Integer; aSt: String; aReal: Double; anAlign: TAlign; aForm: TMainForm);
  25.     procedure ShowInMemo(aMemo: TMemo);
  26.   end;
  27.  
  28. var
  29.   MainForm: TMainForm;
  30.   rec, copyRec: TRec;
  31.  
  32. implementation
  33.  
  34. uses typinfo;
  35.  
  36. {$R *.lfm}
  37.  
  38. procedure TRec.Init(aNum: Integer; aSt: String; aReal: Double; anAlign: TAlign; aForm: TMainForm);
  39. begin
  40.   num:=aNum;
  41.   st:=aSt;
  42.   real:=aReal;
  43.   align:=anAlign;
  44.   form:=aForm;
  45. end;
  46.  
  47. procedure TRec.ShowInMemo(aMemo: TMemo);
  48. begin
  49.   if Assigned(aMemo) then begin
  50.     aMemo.Clear;
  51.     with aMemo.Lines do begin
  52.       Add('Copied record''s field data is as follows:');
  53.       Add('  num=%d',[num]);
  54.       Add('  st="%s"',[st]);
  55.       Add('  real=%f',[real]);
  56.       Add('  align=%s',[GetEnumName(TypeInfo(TAlign), Ord(align))]);
  57.       Add('  form.Name=%s',[form.Name]);
  58.       Add('  form.Tag=%d',[form.Tag]);
  59.       Add('  Assigned(form.OnCreate)=%s',[BoolToStr(Assigned(form.OnCreate),True)]);
  60.       Add('  form.Align=%s',[GetEnumName(TypeInfo(TAlign), Ord(form.Align))]);
  61.     end;
  62.   end;
  63. end;
  64.  
  65. procedure TMainForm.FormCreate(Sender: TObject);
  66. begin
  67.   copyRec:=Default(TRec);
  68.   MainForm.Tag:=9999;
  69.   MainForm.Align:=alClient;
  70.   rec.Init(-34, 'example', 123.456, alRight, MainForm);
  71.   copyRec:=rec;
  72.   copyRec.ShowInMemo(Memo1);
  73. end;
  74.  
  75. end.

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: Copy of record
« Reply #3 on: September 20, 2017, 08:38:25 pm »
An obvious problem is if a record contains a pointer reference to some memory and this reference is copied to another record. When the memory references by the first record is released, the second record has a pointer reference to invalid memory. But this error would of course be related to the thing in front of the screen! :P

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Copy of record
« Reply #4 on: September 20, 2017, 09:35:00 pm »
I do not condone the use of anything else than shortstring in records, but simple assignment copies the record, not the pointer to record.
I do not know what your internet source was smoking, it is wrong. >:D >:(
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode delphi}{$H+}{$endif}
  2. var a,b:record
  3.   s:string;
  4.   i:integer;
  5.   end;
  6. begin
  7.  a.s :='Blaat';
  8.  a.i := 100;
  9.  b := a;  // copies the record, not the pointer, see what happens:
  10.  b.s := 'Blaat some more'; //changes b.s, but a.s is the same
  11.  inc(b.i); // uses the copy value and increment it by one, 101. a.i stays the same.
  12.  writeln(a.s :20,b.s:20, a.i:4,b.i:4);
  13. end.
  14.  
« Last Edit: September 20, 2017, 09:43:21 pm by Thaddy »
Specialize a type, not a var.

guest58172

  • Guest
Re: Copy of record
« Reply #5 on: September 20, 2017, 10:30:01 pm »
Class instances are copied such that published properties and events are also copied, without you having to write anything beyond a simple assignment operator.

What ? classes are reference types so just the reference is copied, i.e the value of an address. To have value semantic on classes we usually override assign() since operator ':=' is not possible w/ classes.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8747
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Copy of record
« Reply #6 on: September 20, 2017, 10:46:34 pm »
So what are the collateral effects if I do so ?
Nothing, if you want a full copy, that's the correct, safety guaranteed way to do it since 1974 (CMIIW), or perhaps it's still an idea in Prof. Wirth's brain.

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Copy of record
« Reply #7 on: September 20, 2017, 10:50:21 pm »
Class instances are copied such that published properties and events are also copied, without you having to write anything beyond a simple assignment operator.

What ? classes are reference types so just the reference is copied, i.e the value of an address. To have value semantic on classes we usually override assign() since operator ':=' is not possible w/ classes.
Right! One remark:
Actually, do not refer to Assign, because Assign can be both implemented as shallow or deep copy.... And shit happens.... :P I see your point, but..You are actually saying what I just did..
« Last Edit: September 20, 2017, 10:52:04 pm by Thaddy »
Specialize a type, not a var.

guest58172

  • Guest
Re: Copy of record
« Reply #8 on: September 20, 2017, 11:27:27 pm »
Class instances are copied such that published properties and events are also copied, without you having to write anything beyond a simple assignment operator.

What ? classes are reference types so just the reference is copied, i.e the value of an address. To have value semantic on classes we usually override assign() since operator ':=' is not possible w/ classes.
Right! One remark:
Actually, do not refer to Assign, because Assign can be both implemented as shallow or deep copy.... And shit happens.... :P I see your point, but..You are actually saying what I just did..

I don't think i would have reacted like i have if you meant the same thing bu anyway...

A part of the problem is that in Object Pascal, records are not much used. Languages where records are more used have facilities to solve this problem, I think especially to D which, in addition to the blit copy using "=" has a system called "postblit" which is used to handle the case of struct members that contain indirections (e.g arrays, classes). I wont do too much D propaganda here but a small demo: https://www.ideone.com/PVRX0F

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: Copy of record
« Reply #9 on: September 21, 2017, 02:58:33 am »
A part of the problem is that in Object Pascal, records are not much used. Languages where records are more used have facilities to solve this problem, I think especially to D which, in addition to the blit copy using "=" has a system called "postblit" which is used to handle the case of struct members that contain indirections (e.g pointer, classes). I wont do too much D propaganda here but a small demo: https://www.ideone.com/PVRX0F

I definitely agree with you about Pascal programmers not using records enough... especially now that "Advanced Records" are fully featured. Advanced Records solve a LOT of the memory management problems that classes have, and also more usefully allow for easy access by any function or procedure that takes a typed pointer as a parameter. For example, they're especially handy in OpenGL and other graphics heavy applications, as they are guaranteed to be exactly the size in bytes of the sum of their fields, and are guaranteed to have that data laid out in linear order. (Which is of course obviously not the case with classes.)

I think a big part of it is people being stuck in their ways and saying "rargh, records should ONLY be containers for data! For them to have their own methods just doesn't sit right with me, and seems so un-Pascalish!" (Which IMO is a ridiculous sentiment to have... it amounts to unnecessarily making things harder for yourself while developing for the sole purpose of maintaining some abstract idea you have about langue "purity".)

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Copy of record
« Reply #10 on: September 21, 2017, 03:46:44 am »
in case anyone has forgotten there are OBJECTS which also can move data around
like Records and contain methods etc.

 As far as I am concerned they have not died and it seems that they are coming back
but only under a different name with maybe some restrictions.
The only true wisdom is knowing you know nothing

guest58172

  • Guest
Re: Copy of record
« Reply #11 on: September 21, 2017, 04:39:48 am »
One thing that's really crazy is that iterators are not records, even if this would require duck types and a lot of templates to be generalized in the FCL.

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: Copy of record
« Reply #12 on: September 21, 2017, 05:26:43 am »
in case anyone has forgotten there are OBJECTS which also can move data around
like Records and contain methods etc.

 As far as I am concerned they have not died and it seems that they are coming back
but only under a different name with maybe some restrictions.

Yes, but they're buggy and unmaintained. There's no reason to use them over "Advanced Records".

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Copy of record
« Reply #13 on: September 21, 2017, 08:47:08 am »
Yes, but they're buggy and unmaintained. There's no reason to use them over "Advanced Records".
They are not buggy, they are mature.
Because their stack oriented nature they are susceptible to bad programmers, though. Especially younger ones.
That's something else than buggy.
They are also maintained. New language features are often available for objects too.

Please give us an example where objects are buggy? 99.99% chance it is the programmer that is buggy.
I know, the whole KOL library is based on old school objects.

Note: in Delphi they are not really maintained, but still stable.
« Last Edit: September 21, 2017, 09:23:24 am by Thaddy »
Specialize a type, not a var.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Copy of record
« Reply #14 on: September 21, 2017, 10:08:08 am »
in case anyone has forgotten there are OBJECTS which also can move data around
like Records and contain methods etc.

 As far as I am concerned they have not died and it seems that they are coming back
but only under a different name with maybe some restrictions.

Yes, but they're buggy and unmaintained. There's no reason to use them over "Advanced Records".
inheritance.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018