digitalmars.D - D1/D2: How to check if a method has been overridden
- klickverbot (34/34) Sep 07 2010 Hello all,
- Mafi (9/43) Sep 07 2010 Hi,
- klickverbot (4/5) Sep 07 2010 Unfortunately, the right indeed is a shortcut for the left – the lookup
- dsimcha (19/19) Sep 07 2010 One way to test for overriding at runtime is to compare the function poi...
- klickverbot (4/7) Sep 07 2010 That's basically the same idea I were already using, but have you tried
- dsimcha (10/17) Sep 07 2010 All you need to do is provide an explicit type for the delegate:
- klickverbot (16/16) Sep 07 2010 Putting the overloading issue aside for a moment, how would you
- Jason House (2/21) Sep 07 2010
- bearophile (6/28) Sep 07 2010 Have you tried to compile that code with -w?
- klickverbot (25/30) Sep 07 2010 Well, I guess I should have wrote the following instead:
- klickverbot (1/1) Sep 07 2010 s/have wrote/have written/
- Max Samukha (47/48) Sep 08 2010 You can avoid messing with vtable:
- klickverbot (3/3) Sep 08 2010 Hm, strange, this is more or less the same solution I was using up to
- klickverbot (4/4) Sep 13 2010 Thanks a lot, Max, for some reason this works, while my own, very
- Max Samukha (8/12) Sep 13 2010 In old times &ClassName.foo used to give you exactly what you would
- Kagamin (2/4) Sep 07 2010 Isn't this info available through classinfo?
- klickverbot (4/5) Sep 08 2010 How exactly would you look this up using classinfo? Maybe it's the lack
- Kagamin (2/8) Sep 08 2010 MemberInfo_function has fp member.
- Jacob Carlborg (5/9) Sep 08 2010 In D2 there is a way to get all the members of a class, including
Hello all, as some of you might know, I have started working on a D module for SWIG quite some time ago. In the meantime, the project is almost ready for inclusion in SWIG trunk as a full-fledged language module supporting D1/Tango and D2/Phobos. However, there is one major blocker left: I need to check if a method has been overridden for this in a potential subclass (obviously at runtime), as illustrated below. --- class A { void foo( float a ) {} void foo( int a ) {} final void bar() { // Determine whether this.foo( 1 ) and this.foo( 1f ) really refer // to A.foo( float ) and A.foo( int ) or if they point to a subclass // implementation – how? } } class B : A { override void foo( float a ) {} } class C : A { override void foo( int a ) {} } class D : B { override void foo( int a ) {} } --- Until DMD 1.047, I have used a piece of code shown in http://d.puremagic.com/issues/show_bug.cgi?id=4835, but the casts in there are no longer enough for DMD to determine which overload is being referred to. Now, please tell me that there _is_ a way to do this (D1 and D2, but I don't mind if have to generate different code for the both)…
Sep 07 2010
Am 07.09.2010 23:00, schrieb klickverbot:Hello all, as some of you might know, I have started working on a D module for SWIG quite some time ago. In the meantime, the project is almost ready for inclusion in SWIG trunk as a full-fledged language module supporting D1/Tango and D2/Phobos. However, there is one major blocker left: I need to check if a method has been overridden for this in a potential subclass (obviously at runtime), as illustrated below. --- class A { void foo( float a ) {} void foo( int a ) {} final void bar() { // Determine whether this.foo( 1 ) and this.foo( 1f ) really refer // to A.foo( float ) and A.foo( int ) or if they point to a subclass // implementation – how? } } class B : A { override void foo( float a ) {} } class C : A { override void foo( int a ) {} } class D : B { override void foo( int a ) {} } --- Until DMD 1.047, I have used a piece of code shown in http://d.puremagic.com/issues/show_bug.cgi?id=4835, but the casts in there are no longer enough for DMD to determine which overload is being referred to. Now, please tell me that there _is_ a way to do this (D1 and D2, but I don't mind if have to generate different code for the both)…Hi, couldn't you just check if a delegate's funcptr is the same as the real funcptr: &this.foo == &foo I'm not sure if the right isn't an shortcut for the left and it could get weird with strange linking but if D really want's to be a system's language then this should work. Mafi
Sep 07 2010
On 9/7/10 11:07 PM, Mafi wrote:I'm not sure if the right isn't an shortcut for the left […]Unfortunately, the right indeed is a shortcut for the left – the lookup is performed using the vtbl. Furthermore, this would not solve my problem with overloaded functions.
Sep 07 2010
One way to test for overriding at runtime is to compare the function pointer of a delegate obtained at runtime to the function pointer obtained from the compile time type. Here's a simplified example: import std.stdio; class A { void fun() {} } class B : A { override void fun() {} } void main() { auto a = new A; auto b = new B; auto aDel = &a.fun; auto bDel = &b.fun; writeln(&A.fun is aDel.funcptr); // True: fun is not overridden writeln(&A.fun is bDel.funcptr); // False: fun is overridden }
Sep 07 2010
On 9/7/10 11:12 PM, dsimcha wrote:One way to test for overriding at runtime is to compare the function pointer of a delegate obtained at runtime to the function pointer obtained from the compile time type.That's basically the same idea I were already using, but have you tried implementing it for overloaded functions? I have not gotten this to work since there is seemingly no way to do &a.foo then.
Sep 07 2010
== Quote from klickverbot (see klickverbot.at)'s articleOn 9/7/10 11:12 PM, dsimcha wrote:All you need to do is provide an explicit type for the delegate: class A { void fun(uint num) {} void fun(float num) {} } void main() { auto a = new A; void delegate(float) funDel = &a.fun; }One way to test for overriding at runtime is to compare the function pointer of a delegate obtained at runtime to the function pointer obtained from the compile time type.That's basically the same idea I were already using, but have you tried implementing it for overloaded functions? I have not gotten this to work since there is seemingly no way to do &a.foo then.
Sep 07 2010
Putting the overloading issue aside for a moment, how would you implement it inside a member function of a (which is required for various reasons? The following does *not* work, because &A.foo also performs a vtbl lookup when put inside A… --- class A { void foo() {} void bar() { auto thisDg = &this.foo; writeln(&A.foo is thisDg.funcptr); } } --- Besides, it also returns a delegate because of this, which is why the code does not even compile, but that would be worked around easily.
Sep 07 2010
That looks like something that should go into bugzilla. klickverbot Wrote:Putting the overloading issue aside for a moment, how would you implement it inside a member function of a (which is required for various reasons? The following does *not* work, because &A.foo also performs a vtbl lookup when put inside A… --- class A { void foo() {} void bar() { auto thisDg = &this.foo; writeln(&A.foo is thisDg.funcptr); } } --- Besides, it also returns a delegate because of this, which is why the code does not even compile, but that would be worked around easily.
Sep 07 2010
klickverbot:class A { void foo( float a ) {} void foo( int a ) {} final void bar() { // Determine whether this.foo( 1 ) and this.foo( 1f ) really refer // to A.foo( float ) and A.foo( int ) or if they point to a subclass // implementation – how? } } class B : A { override void foo( float a ) {} } class C : A { override void foo( int a ) {} } class D : B { override void foo( int a ) {} }Have you tried to compile that code with -w? See also: http://d.puremagic.com/issues/show_bug.cgi?id=4216 Bye, bearophile
Sep 07 2010
On 9/7/10 11:31 PM, bearophile wrote:Have you tried to compile that code with -w? See also: http://d.puremagic.com/issues/show_bug.cgi?id=4216 Bye, bearophileWell, I guess I should have wrote the following instead: --- class A { void foo( float a ) {} void foo( int a ) {} final void bar() { // Determine whether this.foo( 1 ) and this.foo( 1f ) really refer // to A.foo( float ) and A.foo( int ) or if they point to a subclass // implementation – how? } } class B : A { alias A.foo foo; override void foo( float a ) {} } class C : A { alias A.foo foo; override void foo( int a ) {} } class D : B { alias B.foo foo; override void foo( int a ) {} } ---
Sep 07 2010
On 09/08/2010 12:33 AM, klickverbot wrote:Well, I guess I should have wrote the following instead:You can avoid messing with vtable: class A { void foo( float a ) {} void foo( int a ) {} // hack to get the static address of an overload private static Fn funcAddr(Fn, alias fn)() { return cast(Fn)&fn; } private bool isOverriden(Dg, alias fn)() { Dg dg = &foo; // check if the static and dynamic addresses match return dg.funcptr != funcAddr!(typeof(dg.funcptr), fn); } final void bar() { writefln("%:", this.classinfo); if (isOverriden!(void delegate(float), foo)) writefln(" foo(float) is overriden"); if (isOverriden!(void delegate(int), foo)) writefln(" foo(int) is overriden"); } } class B : A { alias A.foo foo; override void foo( float a ) {} } class C : A { alias A.foo foo; override void foo( int a ) {} } class D : B { alias B.foo foo; override void foo( int a ) {} } void main() { auto a = new A; a.bar(); a = new B; a.bar(); a = new C; a.bar(); a = new D; a.bar(); } No guarantees at all as you never know whether you are dealing with a bug or feature.
Sep 08 2010
Hm, strange, this is more or less the same solution I was using up to DMD 1.047, but it seems to work on DMD 2.048 too – I'll investigate why… Thanks a lot, anyway.
Sep 08 2010
Thanks a lot, Max, for some reason this works, while my own, very similar solution doesn't. Unfortunately, however, this exposes yet another DMD bug: http://d.puremagic.com/issues/show_bug.cgi?id=4860.
Sep 13 2010
On 09/13/2010 05:56 PM, klickverbot wrote:Thanks a lot, Max, for some reason this works, while my own, very similar solution doesn't.In old times &ClassName.foo used to give you exactly what you would expect - the static address of foo. That was extremely useful but "unsafe" because the actual type of the function differed from the type of the function pointer. Things changed at some point and nobody knows whether it is a regression or by design because this feature has never been specified.Unfortunately, however, this exposes yet another DMD bug: http://d.puremagic.com/issues/show_bug.cgi?id=4860.A bad one.
Sep 13 2010
klickverbot Wrote:Now, please tell me that there _is_ a way to do this (D1 and D2, but I don't mind if have to generate different code for the both)…Isn't this info available through classinfo?
Sep 07 2010
On 9/8/10 8:25 AM, Kagamin wrote:Isn't this info available through classinfo?How exactly would you look this up using classinfo? Maybe it's the lack of documentation, but I didn't see a way to achieve that with Classinfo and friends…
Sep 08 2010
klickverbot Wrote:On 9/8/10 8:25 AM, Kagamin wrote:MemberInfo_function has fp member.Isn't this info available through classinfo?How exactly would you look this up using classinfo? Maybe it's the lack of documentation, but I didn't see a way to achieve that with Classinfo and friends…
Sep 08 2010
On 2010-09-08 08:25, Kagamin wrote:klickverbot Wrote:In D2 there is a way to get all the members of a class, including methods. But it doesn't currently work due to some bugs. -- /Jacob CarlborgNow, please tell me that there _is_ a way to do this (D1 and D2, but I don't mind if have to generate different code for the both)…Isn't this info available through classinfo?
Sep 08 2010