Discussion:
[fpc-devel] sizeof member in class procedure
Benito van der Zander
2018-08-14 22:30:35 UTC
Permalink
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
Post by Benito van der Zander
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
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
Post by Marco van de Voort
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
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;
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.
_______________________________________________
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
Post by 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...