Re: [fpc-devel] comparing methods

2009-09-15 Thread Den Jean
On Sunday 13 September  2009 23:38:08 Jonas Maebe wrote:
> If the behaviour is different in Delphi.
at least in kylix.

this works in kylix and not in fpc

$ cat hooks2.pas   
program hooks;

{$IFDEF FPC}
{$mode delphi}
{$ENDIF}  

uses SysUtils,Classes,Types;

{$IFNDEF FPC}
type PtrUInt = DWord; // DCC is 32 bit
function HexStr(P:Pointer) : String;  
begin 
HexStr:=IntToHex(PtrUInt(P),4);   
end;  
{$ENDIF}  

type
  TMethod_1Param = procedure(Value:integer=0) of object;

  procedure Hook_M_1Param(aMethod: TMethod_1Param);
  begin
  writeln('Hooked: Method.Code:',HexStr(TMethod(aMethod).Data),
  '  Method.Data:',HexStr(TMethod(aMethod).Code)); 
  TMethod_1Param(aMethod)(143);
  end; 

type
  TC = class(TObject)
  public
  F : integer;
  constructor Create;
  procedure M_1Param(Value:integer=0);
  end;

  constructor TC.Create;
  begin
  inherited Create;
  F:=142;
  Hook_M_1Param(M_1Param);
  end;

  procedure TC.M_1Param(Value:integer);
  begin
  writeln('M_1Param called with Value:',Value,' and F is:',F);
  end;


var
  C : TC;

begin
C:=TC.Create;
end.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-13 Thread Jonas Maebe


On 13 Sep 2009, at 23:32, Den Jean wrote:


On Sunday 13 September  2009 22:05:17 Jonas Maebe wrote:
That's why in objfpc mode you can (have to) use Hook_Signal 
(@MyMethod)

I was rather hoping for an answer/fix for Delphi Mode.
May I consider it a bug and file one ?


If the behaviour is different in Delphi.


Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-13 Thread Den Jean
On Sunday 13 September  2009 22:05:17 Jonas Maebe wrote:
> That's why in objfpc mode you can (have to) use Hook_Signal(@MyMethod)  
I was rather hoping for an answer/fix for Delphi Mode.
May I consider it a bug and file one ?

kind regards,

Den Jean



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-13 Thread Jonas Maebe


On 13 Sep 2009, at 22:02, Den Jean wrote:


So I cannot directly give the hooked procedure as a parameter
to a procedure, I have to do stuff like this
var M : TMethod
TSomeMethodTyp(M):=MyMethod
Hook_Signal(M);
Instead of
Hook_Signal(MyMethod)


That's why in objfpc mode you can (have to) use Hook_Signal(@MyMethod)  
and everything is unambiguous.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-13 Thread Den Jean
On Thursday 10 September  2009 16:56:20 Peter Vreman wrote:
> You can use the TMethod record to access the fields:
>   writeln(hexstr(tmethod(@c.p).data));
>   writeln(hexstr(tmethod(@c.p).code));
> end.
kind of related to this,

In the Qt binding I had to revert to a non type safe method 
for signal hooking. Because the compiler does not always see
the difference between a method provide to a procedure 
as a parameter and calling the method and giving the
method result as a parameter to the procedure.

So I cannot directly give the hooked procedure as a parameter
to a procedure, I have to do stuff like this
var M : TMethod
TSomeMethodTyp(M):=MyMethod
Hook_Signal(M);
Instead of 
Hook_Signal(MyMethod)

The following code shows the problem of 
default parameters confusing the compiler:
(compile with or w/o define DEFINE DEFAULT_VALUE.)

program hooks;

{$mode delphi}

{$DEFINE DEFAULT_VALUE}

uses SysUtils,Classes,Types;



{$IFNDEF DEFAULT_VALUE}
type
  TMethod_1Param = procedure(Value:integer) of object;

  procedure Hook_M_1Param(aMethod: TMethod_1Param);
  begin
  writeln('Hooked: Method.Code:',HexStr(TMethod(aMethod).Data),' 
Method.Data:',HexStr(TMethod(aMethod).Code));
  TMethod_1Param(aMethod)(143);
  end;
{$ELSE}
type
  TMethod_1Param = procedure(Value:integer=0) of object;

  procedure Hook_M_1Param(aMethod: TMethod);
  begin
  writeln('Hooked: Method.Code:',HexStr(aMethod.Data),' 
Method.Data:',HexStr(aMethod.Code));
   
  TMethod_1Param(aMethod)(143);
  end;
{$ENDIF}


type
  TC = class(TObject)
  public
  F : integer; 
  constructor Create;
  {$IFNDEF DEFAULT_VALUE}
  procedure M_1Param(Value:integer);
  {$ELSE}
  procedure M_1Param(Value:integer=0);
  {$ENDIF}
  end;

  constructor TC.Create;
  {$IFDEF DEFAULT_VALUE}
  var M : TMethod;
  {$ENDIF}
  begin
  inherited Create;
  F:=142;

  {$IFNDEF DEFAULT_VALUE}
  Hook_M_1Param(M_1Param);
  {$ELSE}
  TMethod_1Param(M):=M_1Param;
  Hook_M_1Param(M);
   {$ENDIF}
  
  end;

  procedure TC.M_1Param(Value:integer);
  begin
  writeln('M_1Param called with Value:',Value,' and F is:',F);
  end;


var
  C : TC;
  {$IFDEF DEFAULT_VALUE}
  M : TMethod;
  {$ENDIF}

begin
C:=TC.Create;

{$IFNDEF DEFAULT_VALUE}
writeln('C.Instance:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Data));
writeln('C.M_1Param:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Code));
{$ELSE}
// Uncomment the following lines to have a compiler error.
// Illegal type conversion: "untyped" to "
//writeln('C.Instance:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Data));
//writeln('C.M_1Param:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Code));
// Trick with MethodType casting a Method variable
TMethod_1Param(M):=C.M_1Param;
writeln('C.Instance:',HexStr(M.Data));
writeln('C.M_1Param:',HexStr(M.Code));
{$ENDIF}

end.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-12 Thread Martin Schreiber
On Saturday 12 September 2009 10:07:55 Mattias Gaertner wrote:
> On Sat, 12 Sep 2009 09:33:11 +0200
>
>
> Martin, I hope you mean Data=ID and Code=nil.
>
Yup, you are right, thanks for correcting. 

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-12 Thread Mattias Gaertner
On Sat, 12 Sep 2009 09:33:11 +0200
Martin Schreiber  wrote:

> On Thursday 10 September 2009 19:42:22 Ivo Steinmann wrote:
> > Florian Klaempfl schrieb:
> > > Ivo Steinmann schrieb:
> > >> 1. Using =nil or Assigned should result in the same.
> > >
> > > Afaik not, this was one of the reasons for assigned.
> > >
> >
> > well, nobody seems to know it...  eg. if you go through code in rtl
> > (classes, etc...) sometimes =nil is used, sometimes Assigned. it's a
> > complete random mix. I don't think that this "mix" was intention.
> 
> IDE's (Delphi, MSEide, don't know about Lazarus) store a method index
> number in TMethod.Code in published method properties because there
> is no code for the handler available at designtime, TMethod.Data is
> nil. For designtime running software (RTL, FCL, components...)
> *always* use assigned() in order to check if a method property is set
> before calling the handler or you will call the the indexnumber which
> probably want work well. ;-)
> This is probably the reason using =nil or assigned() depending on the
> task in Classes.

Martin, I hope you mean Data=ID and Code=nil.

Delphi and Lazarus uses this and Assigned and <>nil check only
Code, not Data. If MSEgui allows to use components from the FCL, then it
should leave Code=nil.


Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-12 Thread Martin Schreiber
On Thursday 10 September 2009 19:42:22 Ivo Steinmann wrote:
> Florian Klaempfl schrieb:
> > Ivo Steinmann schrieb:
> >> 1. Using =nil or Assigned should result in the same.
> >
> > Afaik not, this was one of the reasons for assigned.
> >
>
> well, nobody seems to know it...  eg. if you go through code in rtl
> (classes, etc...) sometimes =nil is used, sometimes Assigned. it's a
> complete random mix. I don't think that this "mix" was intention.

IDE's (Delphi, MSEide, don't know about Lazarus) store a method index number 
in TMethod.Code in published method properties because there is no code for 
the handler available at designtime, TMethod.Data is nil.
For designtime running software (RTL, FCL, components...)  *always* use 
assigned() in order to check if a method property is set before calling the 
handler or you will call the the indexnumber which probably want work 
well. ;-)
This is probably the reason using =nil or assigned() depending on the task in 
Classes.

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-11 Thread Mattias Gärtner

Zitat von Michael Schnell :


Mattias Gärtner wrote:


The @ operator is more than "address of".



Hmm "Address of" is not that simple in itself. :)

With a "Procedure of Object", "@" of course handles the Self pointer, too.

I suppose to find the address of a function "@" uses the Virtual Method
Table found with the Self pointer.

So in fact there are (at least) two ways of implementing a compare
between two pointers to "Procedure of Object" variables, that IMHO both
make sense:

1) Simply compare the Self and the Address part (the same function of
two implementations of a class are different)

2) Compare only the address (the same function of two implementations of
a class are identical, unless overloaded by a child's function).

I think it's a matter of taste (I do vote for (2) ).


No.
It is a matter of consistency.

The current comparison is not intuitive. This is proven by the many  
places where it used wrong and the almost zero places where it is used  
right (Is there any one at all?).


The problems are:

1. It exists for years, so there might be code depending on this. I  
doubt this.


2. It is Delphi/TP compatible. So it can not be done in mode  
delphi/tp. That's why I propose to change it in mode objfpc.


If the compiler team refuses to change it, can at least a "hint" be given?


Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-11 Thread Nino Luciani
On Thursday 10 September 2009 17:52:44 Florian Klaempfl wrote:
> Ivo Steinmann schrieb:
> > 1. Using =nil or Assigned should result in the same.
>
> Afaik not, this was one of the reasons for assigned.
>

I have always used Assigned() to test whether a pointer is 'valid' or is nil. 
Thus Assiged() should return False if pointer is nil?


procedure Test;
var
  myPtr : PChar;

begin
  // Pointer variables are not set to nil by default
  if Assigned(myPtr) then 
ShowMessage('myPtr is not nil')
  else
ShowMessage('myPtr is nil');

  // So we must set them to nil to be sure that they are undefined
  myPtr := Nil;
  if Assigned(myPtr) then 
   ShowMessage('myPtr is still not nil')
  else
   ShowMessage('myPtr is nil');
end;

if you don't agree, don't blame me.
http://www.delphibasics.co.uk/RTL.asp?Name=Assigned
> ___
> fpc-devel maillist  -  fpc-devel@lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-devel

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-11 Thread Michael Schnell
Mattias Gärtner wrote:
> 
> The @ operator is more than "address of".
> 

Hmm "Address of" is not that simple in itself. :)

With a "Procedure of Object", "@" of course handles the Self pointer, too.

I suppose to find the address of a function "@" uses the Virtual Method
Table found with the Self pointer.

So in fact there are (at least) two ways of implementing a compare
between two pointers to "Procedure of Object" variables, that IMHO both
make sense:

1) Simply compare the Self and the Address part (the same function of
two implementations of a class are different)

2) Compare only the address (the same function of two implementations of
a class are identical, unless overloaded by a child's function).

I think it's a matter of taste (I do vote for (2) ).

-Michael


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Sergei Gorelkin

Michael Van Canneyt wrote:



On Thu, 10 Sep 2009, Florian Klaempfl wrote:


Mattias Gaertner schrieb:

On Thu, 10 Sep 2009 17:52:44 +0200
Florian Klaempfl  wrote:


Ivo Steinmann schrieb:

1. Using =nil or Assigned should result in the same.

Afaik not, this was one of the reasons for assigned.


Are there any other reasons for assigned?


Distinction between f=nil and f=nil ;)? When it was introduced, I guess
f()=nil was not possible.


Another idea was that Assigned() could test if a pointer was within
range of the heap.

To my knowledge, in Delphi Assigned() tests only the high-order word of 
the pointer, thus returning False for everything below 64k.


Sergei
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Ivo Steinmann

Florian Klaempfl schrieb:

Ivo Steinmann schrieb:
  

1. Using =nil or Assigned should result in the same.



Afaik not, this was one of the reasons for assigned.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

  
well, nobody seems to know it...  eg. if you go through code in rtl 
(classes, etc...) sometimes =nil is used, sometimes Assigned. it's a 
complete random mix. I don't think that this "mix" was intention.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Michael Van Canneyt



On Thu, 10 Sep 2009, Florian Klaempfl wrote:


Mattias Gaertner schrieb:

On Thu, 10 Sep 2009 17:52:44 +0200
Florian Klaempfl  wrote:


Ivo Steinmann schrieb:

1. Using =nil or Assigned should result in the same.

Afaik not, this was one of the reasons for assigned.


Are there any other reasons for assigned?


Distinction between f=nil and f=nil ;)? When it was introduced, I guess
f()=nil was not possible.


Another idea was that Assigned() could test if a pointer was within
range of the heap.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Florian Klaempfl
Mattias Gaertner schrieb:
> On Thu, 10 Sep 2009 17:52:44 +0200
> Florian Klaempfl  wrote:
> 
>> Ivo Steinmann schrieb:
>>> 1. Using =nil or Assigned should result in the same.
>> Afaik not, this was one of the reasons for assigned.
> 
> Are there any other reasons for assigned?

Distinction between f=nil and f=nil ;)? When it was introduced, I guess
f()=nil was not possible.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Mattias Gaertner
On Thu, 10 Sep 2009 17:52:44 +0200
Florian Klaempfl  wrote:

> Ivo Steinmann schrieb:
> > 
> > 1. Using =nil or Assigned should result in the same.
> 
> Afaik not, this was one of the reasons for assigned.

Are there any other reasons for assigned?

Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Martin

Mattias Gärtner wrote:

Zitat von Michael Schnell :

Mattias Gärtner wrote:

Can someone explain why in mode objfpc comparing methods only compares
the address, but not the instance?

Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".


Most interesting.
I also always sought @Instance.Method, returns a TMethod record (that is 
the address of the instance and the address of the Code).


But mor interesting: There a various mails/requests about: 
- overloading by result
- automatic extending a calculation to the type of the result AInteger 
:= AByte + AByte can cause an overflow, even though the result would 
have enough space


Every time the answer includes something like: The evaluation of an 
expression (rvalue) is done independent of the type of the variable to 
which it will be assigned (lvalue) .

A statement I do agree with 100%.
Therefore in "Int := Byte + Byte" the rvalue is calculated using bytes. 
And therefore an overload by result is not possible as when evaluating 
what to call, the type of the lvalue is unknown.


And now I am reading this mail, and unless I misunderstood something:
The result of @Instance.Method depends on the lvalue's type or the 
context? (assignment vs compare).


That seems to be in direct disagreement to the above statement?

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Florian Klaempfl
Ivo Steinmann schrieb:
> 
> 1. Using =nil or Assigned should result in the same.

Afaik not, this was one of the reasons for assigned.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Desmond Coertzen
Thank you Peter.

TMethod would have been handy if i knew about this back then. For delphi
compatibility, I had to do this:

program methodpointer;

uses
  Classes, sysutils;

type
  TMyEvent = procedure of object;

  TMyClass = class(TObject)
procedure MyMethod;
  end;

{ TMyClass }

procedure TMyClass.MyMethod;
begin
end;

var
  MyEvent : TMyEvent;
  Addr: ^TMethod;
  MyClass: TMyClass = nil;

begin
  writeln(hexStr(TMethod(TMyEvent(MyClass.MyMethod)).Code));
  writeln(hexStr(TMethod(TMyEvent(MyClass.MyMethod)).Data));
  MyClass := TMyClass.Create;
  writeln(hexStr(TMethod(TMyEvent(MyClass.MyMethod)).Code));
  writeln(hexStr(TMethod(TMyEvent(MyClass.MyMethod)).Data));
  FreeAndNil(MyClass);
end.

On Thu, Sep 10, 2009 at 2:56 PM, Peter Vreman wrote:

> On Thu, 10 Sep 2009 14:25:26 +, Desmond Coertzen
>  wrote:
> > I have done some horrible code where I needed to know the following:
> >
> > If TSomeProc = procedure(), then is it easy to determine or set
> entry
> > vector of ThatProc: TSomeProc by stating ThatProc :=
> > @ProcWhereTheCodeLives_InTheCodeSegment;
> >
> > It gets more difficult when you work with TSomeClassProc =
> procedure()
> > of object, because two parts are referenced here: 1) The entry vector
> where
> > the code lives, 2) The heap address where the object struct lives.
> (Known
> > as
> > the Self variable in a procedure of object)
> >
> > I have worked out which pointer of the two pointers belongs to the code
> and
> > which to the instance with a trial. With a move operation, I was able to
> > manipulate the two pointers, specifically to determine the address of
> the
> > instance.
> >
> > The @ operator only gives you access to the procedure part. Is there, or
> > will there be, another operator to give you access to the instance
> address?
> >
>
> You can use the TMethod record to access the fields:
>
> {$mode objfpc}
> type
>  tc=class
>procedure p;
>  end;
> procedure tc.p;
> begin
> end;
> var
>  c : tc;
> begin
>  writeln(hexstr(tmethod(@c.p).data));
>  writeln(hexstr(tmethod(@c.p).code));
>
>  c:=tc.create;
>  writeln(hexstr(tmethod(@c.p).data));
>  writeln(hexstr(tmethod(@c.p).code));
> end.
>
> ___
> fpc-devel maillist  -  fpc-devel@lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-devel
>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Ivo Steinmann

Mattias Gärtner schrieb:

Zitat von Vincent Snijders :


Jonas Maebe schreef:


On 10 Sep 2009, at 14:01, Mattias Gärtner wrote:



Mattias Gärtner wrote:
Can someone explain why in mode objfpc comparing methods only 
compares

the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".


The current behaviour has been there since svn revision 1, so it's 
quite old and established at least (and Delphi/TP-compatible, afaik).


It is delphi compatible, not really intuitive, so I would welcome a 
change in the objfpc mode.


See:
http://bugs.freepascal.org/view.php?id=9228
http://bugs.freepascal.org/view.php?id=11868


To draw the whole picture:

var a,b: TNotifyEvent;

a=b compares only Code, not Data
a=nil   compares only Data, not Code
Assigned(a) compares only Code, not Data
n.a.compares both

I wonder how many programmers know this.

Even the FCL contains code, where this leads to wrong code.
More important: I don't know a place, where a=b and a=nil are used 
right. But I have seen a lot of code where it was used wrong.



Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

if that's true, then it's the biggest crap I ever heard ;) it must be 
fixed i'm using those kind of compares all over the place, but I 
never noticed this difference.


1. Using =nil or Assigned should result in the same.
2. a=b comparing only code is ok
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Peter Vreman
On Thu, 10 Sep 2009 14:25:26 +, Desmond Coertzen
 wrote:
> I have done some horrible code where I needed to know the following:
> 
> If TSomeProc = procedure(), then is it easy to determine or set
entry
> vector of ThatProc: TSomeProc by stating ThatProc :=
> @ProcWhereTheCodeLives_InTheCodeSegment;
> 
> It gets more difficult when you work with TSomeClassProc =
procedure()
> of object, because two parts are referenced here: 1) The entry vector
where
> the code lives, 2) The heap address where the object struct lives.
(Known
> as
> the Self variable in a procedure of object)
> 
> I have worked out which pointer of the two pointers belongs to the code
and
> which to the instance with a trial. With a move operation, I was able to
> manipulate the two pointers, specifically to determine the address of
the
> instance.
> 
> The @ operator only gives you access to the procedure part. Is there, or
> will there be, another operator to give you access to the instance
address?
> 

You can use the TMethod record to access the fields:

{$mode objfpc}
type
  tc=class
procedure p;
  end;
procedure tc.p;
begin
end;
var
  c : tc;
begin
  writeln(hexstr(tmethod(@c.p).data));
  writeln(hexstr(tmethod(@c.p).code));

  c:=tc.create;
  writeln(hexstr(tmethod(@c.p).data));
  writeln(hexstr(tmethod(@c.p).code));
end.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Desmond Coertzen
I have done some horrible code where I needed to know the following:

If TSomeProc = procedure(), then is it easy to determine or set entry
vector of ThatProc: TSomeProc by stating ThatProc :=
@ProcWhereTheCodeLives_InTheCodeSegment;

It gets more difficult when you work with TSomeClassProc = procedure()
of object, because two parts are referenced here: 1) The entry vector where
the code lives, 2) The heap address where the object struct lives. (Known as
the Self variable in a procedure of object)

I have worked out which pointer of the two pointers belongs to the code and
which to the instance with a trial. With a move operation, I was able to
manipulate the two pointers, specifically to determine the address of the
instance.

The @ operator only gives you access to the procedure part. Is there, or
will there be, another operator to give you access to the instance address?

2009/9/10 Mattias Gärtner 

> Zitat von Vincent Snijders :
>
>  Jonas Maebe schreef:
>>
>>>
>>> On 10 Sep 2009, at 14:01, Mattias Gärtner wrote:
>>>
>>>
> Mattias Gärtner wrote:
>
>> Can someone explain why in mode objfpc comparing methods only compares
>> the address, but not the instance?
>>
>
> Seems perfectly logical to me (@ = Address of, in this case "code
> address", the code is the same for all instances of a class).
>

 OnClick:=...@myclick;

 The @ operator is more than "address of".

>>>
>>> The current behaviour has been there since svn revision 1, so it's quite
>>> old and established at least (and Delphi/TP-compatible, afaik).
>>>
>>
>> It is delphi compatible, not really intuitive, so I would welcome a change
>> in the objfpc mode.
>>
>> See:
>> http://bugs.freepascal.org/view.php?id=9228
>> http://bugs.freepascal.org/view.php?id=11868
>>
>
> To draw the whole picture:
>
> var a,b: TNotifyEvent;
>
> a=b compares only Code, not Data
> a=nil   compares only Data, not Code
> Assigned(a) compares only Code, not Data
> n.a.compares both
>
> I wonder how many programmers know this.
>
> Even the FCL contains code, where this leads to wrong code.
> More important: I don't know a place, where a=b and a=nil are used right.
> But I have seen a lot of code where it was used wrong.
>
>
> Mattias
>
>
> ___
> fpc-devel maillist  -  fpc-devel@lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-devel
>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Mattias Gärtner

Zitat von Vincent Snijders :


Jonas Maebe schreef:


On 10 Sep 2009, at 14:01, Mattias Gärtner wrote:



Mattias Gärtner wrote:

Can someone explain why in mode objfpc comparing methods only compares
the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".


The current behaviour has been there since svn revision 1, so it's  
quite old and established at least (and Delphi/TP-compatible, afaik).


It is delphi compatible, not really intuitive, so I would welcome a  
change in the objfpc mode.


See:
http://bugs.freepascal.org/view.php?id=9228
http://bugs.freepascal.org/view.php?id=11868


To draw the whole picture:

var a,b: TNotifyEvent;

a=b compares only Code, not Data
a=nil   compares only Data, not Code
Assigned(a) compares only Code, not Data
n.a.compares both

I wonder how many programmers know this.

Even the FCL contains code, where this leads to wrong code.
More important: I don't know a place, where a=b and a=nil are used  
right. But I have seen a lot of code where it was used wrong.



Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Mattias Gärtner

Zitat von Jonas Maebe :



On 10 Sep 2009, at 14:01, Mattias Gärtner wrote:



Mattias Gärtner wrote:

Can someone explain why in mode objfpc comparing methods only compares
the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".


The current behaviour has been there since svn revision 1, so it's  
quite old and established at least (and Delphi/TP-compatible, afaik).


Yes, and since the beginning I was wondering why. Years ago I thought,  
there are probably cases where this is useful. But since today I  
hardly saw one. OTOH I saw several times code that misused it.
If it is only for delphi/tp compatibility, then maybe it can be  
changed in mode objfpc?



Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Mattias Gärtner

Zitat von Thaddy :


Mattias Gärtner wrote:

Zitat von Michael Schnell :


Mattias Gärtner wrote:

Can someone explain why in mode objfpc comparing methods only compares
the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".

Nope, it is: although there is some vmt work involved : the data  
part is for the new instance, not the global instance. Assigning a  
new method to one of the two instances your example gives makes them  
unequal because the instances are deep copies or rather new  
instances of the same class with different addresses. Hopes that  
helps.


Not at all. But thanks for trying.



If you assign to an empty variable, like

var a,b:TMyClass;
begin
b:= TMyClass.Create;
a:=b;
end;

You will get the result you expect.


The 'a,b' above are pointers to mem areas. a=b compares the pointers.
If a,b would be records then a=b would compare the mem.
If a,b would be 'procedure of object' then a=b compares only half of  
the mem. This is different to both cases above.

Hope this helps.

Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Vincent Snijders

Jonas Maebe schreef:


On 10 Sep 2009, at 14:01, Mattias Gärtner wrote:



Mattias Gärtner wrote:

Can someone explain why in mode objfpc comparing methods only compares
the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".


The current behaviour has been there since svn revision 1, so it's quite 
old and established at least (and Delphi/TP-compatible, afaik).


It is delphi compatible, not really intuitive, so I would welcome a change in the 
objfpc mode.


See:
http://bugs.freepascal.org/view.php?id=9228
http://bugs.freepascal.org/view.php?id=11868

Vincent
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Thaddy

Mattias Gärtner wrote:

Zitat von Michael Schnell :


Mattias Gärtner wrote:

Can someone explain why in mode objfpc comparing methods only compares
the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".

Nope, it is: although there is some vmt work involved : the data part is 
for the new instance, not the global instance. Assigning a new method to 
one of the two instances your example gives makes them unequal because 
the instances are deep copies or rather new instances of the same class 
with different addresses. Hopes that helps.


If you assign to an empty variable, like

var a,b:TMyClass;
begin
b:= TMyClass.Create;
a:=b;
end;

You will get the result you expect.

Again, very basic.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Jonas Maebe


On 10 Sep 2009, at 14:01, Mattias Gärtner wrote:



Mattias Gärtner wrote:
Can someone explain why in mode objfpc comparing methods only  
compares

the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".


The current behaviour has been there since svn revision 1, so it's  
quite old and established at least (and Delphi/TP-compatible, afaik).



Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Mattias Gärtner

Zitat von Michael Schnell :


Mattias Gärtner wrote:

Can someone explain why in mode objfpc comparing methods only compares
the address, but not the instance?


Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).


OnClick:=...@myclick;

The @ operator is more than "address of".


Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Thaddy

Mattias Gärtner wrote:

Hi,

Can someone explain why in mode objfpc comparing methods only compares 
the address, but not the instance?

For example:

  a:=TMyClass.Create;
  b:=TMyClass.Create;
  if @a.test = @b.test then writeln('the same method');

This results in strange behaviors, when using the following code (from 
the FCL):


property AfterConnect: TNotifyEvent read FAfterConnect write 
SetAfterConnect;


procedure TCustomConnection.SetAfterConnect(const AValue: TNotifyEvent);
begin
  if FAfterConnect=AValue then exit;
  FAfterConnect:=AValue;
end;


Mattias


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


The deep copy versus shallow copy problem.
Depending on what you want. here it is implementing a deep compare, (an 
instance full copy) instead of a shallow compare (a pointer copy). Both 
are valid paradigms, but also -very, very - basic computer science. You 
for some reason want a shallow compare, which may or may not be correct, 
depending on your code.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] comparing methods

2009-09-10 Thread Michael Schnell
Mattias Gärtner wrote:
> Can someone explain why in mode objfpc comparing methods only compares
> the address, but not the instance?

Seems perfectly logical to me (@ = Address of, in this case "code
address", the code is the same for all instances of a class).

-Michael
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel