Discussion:
sizeof member in class procedure
(too old to reply)
Benito van der Zander
2018-08-14 22:30:35 UTC
Permalink
Raw Message
Hi,

why is sizeof on object/class fields sometimes allowed and sometimes not?

type TTest = object
  f: integer;
  class procedure test;
end;

class procedure TTest.test;
begin
  writeln(sizeof(f));             // does not compile
  writeln(sizeof(TTest.f));  // compiles
end;

---

type TTest = class
  f: integer;
  class procedure test;
end;

class procedure TTest.test;
begin
  writeln(sizeof(f));             // does not compile
  writeln(sizeof(TTest.f));  // does not compile
end;

surely that should all be equal to sizeof(integer)

Bye,

Benito
Marco van de Voort
2018-08-15 09:50:06 UTC
Permalink
Raw Message
In our previous episode, Benito van der Zander said:
> why is sizeof on object/class fields sometimes allowed and sometimes not?
>
> type TTest = object
> ? f: integer;
> ? class procedure test;
> end;
>
> class procedure TTest.test;
> begin
> ? writeln(sizeof(f));???????????? // does not compile
> ? writeln(sizeof(TTest.f));? // compiles
> end;

For custom types that don't have a predefined IComparer<> instance, afaik
you can define it yourself and set it in the TDictionary<> type.

Just search for I/Tcomparer<> in the generics.* sources.

I do have some example, but that is for the generic sort, not the
dictionary:

program gensort2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils,generics.collections,generics.defaults;

type
TSomeRecord = record
angle:single;
angleasstring:string;
end;
type

TSomeRecordComparer1 = class(TComparer<TSomeRecord>)
public
function Compare(const Left, Right: TSomeRecord): Integer; override;
end;

function TSomeRecordComparer1.Compare(const Left, Right: TSomeRecord):
Integer;
begin
Result := round(left.angle - right.angle);
end;

var some:array of TSomeRecord;
i : integer;
cmp : TSomeRecordComparer1;
begin
cmp:=TSomeRecordComparer1.Create;
setlength(some,6);
some[0].angle:=100; some[1].angle:=25; some[2].angle:=270;
some[3].angle:=90; some[4].angle:=15; some[5].angle:=300;
for i := 0 to length(some)-1 do
some[i].angleasstring:=FloatToStrF(some[i].angle,fffixed,8,4);
// tarray.sort<tsomerecord>(some,cmp,3,3); // partial sort
tarray.sort<tsomerecord>(some,cmp);
for i := 0 to length(some)-1 do
writeln(some[i].angle:10:5,' ',some[i].angleasstring);
readln;
end.
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/
Marco van de Voort
2018-08-15 12:10:25 UTC
Permalink
Raw Message
In our previous episode, Marco van de Voort said:

I accidentally replied the below post to the wrong thread, probably because they were both
about operator definitions. Anyway the post was about the "why can't we
define class operator for old fashion object type" thread, and how to
customize generics.* classes in general:


> For custom types that don't have a predefined IComparer<> instance, afaik
> you can define it yourself and set it in the TDictionary<> type.
>
> Just search for I/Tcomparer<> in the generics.* sources.
>
> I do have some example, but that is for the generic sort, not the
> dictionary:
>
> program gensort2;
>
> {$APPTYPE CONSOLE}
>
> {$R *.res}
>
> uses
> System.SysUtils,generics.collections,generics.defaults;
>
> type
> TSomeRecord = record
> angle:single;
> angleasstring:string;
> end;
> type
>
> TSomeRecordComparer1 = class(TComparer<TSomeRecord>)
> public
> function Compare(const Left, Right: TSomeRecord): Integer; override;
> end;
>
> function TSomeRecordComparer1.Compare(const Left, Right: TSomeRecord):
> Integer;
> begin
> Result := round(left.angle - right.angle);
> end;
>
> var some:array of TSomeRecord;
> i : integer;
> cmp : TSomeRecordComparer1;
> begin
> cmp:=TSomeRecordComparer1.Create;
> setlength(some,6);
> some[0].angle:=100; some[1].angle:=25; some[2].angle:=270;
> some[3].angle:=90; some[4].angle:=15; some[5].angle:=300;
> for i := 0 to length(some)-1 do
> some[i].angleasstring:=FloatToStrF(some[i].angle,fffixed,8,4);
> // tarray.sort<tsomerecord>(some,cmp,3,3); // partial sort
> tarray.sort<tsomerecord>(some,cmp);
> for i := 0 to length(some)-1 do
> writeln(some[i].angle:10:5,' ',some[i].angleasstring);
> readln;
> end.
> _______________________________________________
> fpc-devel maillist - fpc-***@lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
>
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-b
Sven Barth via fpc-devel
2018-08-16 08:30:27 UTC
Permalink
Raw Message
Am 15.08.2018 um 00:30 schrieb Benito van der Zander:
> Hi,
>
> why is sizeof on object/class fields sometimes allowed and sometimes not?
>
> type TTest = object
>   f: integer;
>   class procedure test;
> end;
>
> class procedure TTest.test;
> begin
>   writeln(sizeof(f));             // does not compile
>   writeln(sizeof(TTest.f));  // compiles
> end;
>
> ---
>
> type TTest = class
>   f: integer;
>   class procedure test;
> end;
>
> class procedure TTest.test;
> begin
>   writeln(sizeof(f));             // does not compile
>   writeln(sizeof(TTest.f));  // does not compile
> end;
>
> surely that should all be equal to sizeof(integer)
Interestingly Delphi does not allow it either (though it fails with two
different errors for the two variants (note: I only tested the class
one)), so its behavior is the same as in FPC there. I personally would
say that it should be allowed however... *shrugs*

Regards,
Sven
Loading...