Re: [fpc-devel] comparing methods
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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