Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the size of a Delphi record is not increased when a procedure is included?

I have two records with the same fields and one of them has a set of procedures. Why the Size of both records is the same?

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TData = record
    Age : Byte;
    Id  : Integer;
  end;

  TData2 = record
    Age : Byte;
    Id  : Integer;
    procedure foo1;
    procedure foo2;
    procedure foo3;
  end;

procedure TData2.foo1;
begin

end;

procedure TData2.foo2;
begin

end;

procedure TData2.foo3;
begin

end;

begin
  try
    Writeln('SizeOf(TData) = '+ IntToStr(SizeOf(TData)));
    Writeln('SizeOf(TData2) = '+ IntToStr(SizeOf(TData2)));
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
like image 631
Salvador Avatar asked Jan 16 '13 03:01

Salvador


1 Answers

That's because the record itself only carries with the data that composes the record and no procedures or functions. The procedures and functions are a kind of syntactic sugar to avoid passing the record itself as a parameter: the self variable that is automagically added by the compiler for you.

Each method you declare in a record have another parameter for the record itself, for example:

  TData2 = record
    Age : Byte;
    Id  : Integer;
    procedure Foo1;
    procedure Foo2(SomeParam: Integer);
  end;

is changed to something equivalent to:

  PData2 = ^TData2;

  TData2 = record
    Age : Byte;
    Id  : Integer;
  end;

  procedure TData2_Foo1(Self: PData2);
  procedure TData2_Foo2(Self: PData2; SomeParam: Integer);

end each call you make is also changed, for example:

var
  Data: TData2;
begin
  Data.Foo1;
  Data.Foo2(1);
end;

is changed for something equivalent to:

var
  Data: TData2;
begin
  TData2_Foo1(@Data);
  TData2_Foo1(@Data, 1);
end;

I have no Delphi at hand to check if the parameter is added at the beginning or at the end of your parameter list, but I hope you get the idea.

Of course there's no real syntax for this, since it is done on the fly by the compiler and thus, for example, the procedure names are not changed. I did that in a try to make my answer easy to understand.

like image 163
jachguate Avatar answered Oct 05 '22 01:10

jachguate