digitalmars.D - Method pointers are *function* pointers?? Or delegates??
- Mehrdad (7/7) May 18 2012 My brain just exploded.
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/13) May 18 2012 Delegates. Pointer to member function + class instance.
- Andrei Alexandrescu (3/10) May 18 2012 Looks like a bug. The assert should pass only if foo were static.
- Mehrdad (3/16) May 18 2012 Okay I'll report it... hopefully it isn't just with my version
- Mehrdad (2/4) May 18 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8114
- Steven Schveighoffer (35/46) May 18 2012 No, this is not a bug.
- Mehrdad (6/24) May 18 2012 I actually realized that might be the reason before I reported
- Steven Schveighoffer (3/28) May 18 2012 That would be nice, wouldn't it? :)
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/36) May 18 2012 At least it would prevent writing platform/compiler-specific code...
- Daniel Murphy (4/29) May 18 2012 No, that won't work in all cases due to the ordering of parameters, 'thi...
- Mehrdad (3/5) May 18 2012 Better than not working in /any/ cases lol. :P
- Daniel Murphy (10/15) May 18 2012 I'd actually rather it /didn't/ work in any cases, and just returned voi...
- Mehrdad (2/4) May 18 2012 Well if that's an option then I like that too.
- deadalnix (2/33) May 19 2012 extern(this) and you are done expressing thiscall.
- Andrei Alexandrescu (23/40) May 18 2012 Typing is what it is. The following program is unsound without a cast in...
- deadalnix (7/49) May 19 2012 It would be nice, but require a way to express that calling convention
- Steven Schveighoffer (22/63) May 22 2012 Poor design? Yes. Bug? no. It's behavior is very intentional and has ...
- Jacob Carlborg (13/32) May 22 2012 It needs to be possible to compose delegates:
- Steven Schveighoffer (9/34) May 22 2012 Error, cannot cast function of type void function(Foo this) to void
- Jacob Carlborg (8/31) May 22 2012 I have no problem with a couple of case, as long as it's possible to
- Andrei Alexandrescu (8/26) May 22 2012 Initialization with void is a feature. My example shows the fail of a
- Steven Schveighoffer (8/23) May 22 2012 Your example shows an invalid use for a feature. There are valid uses f...
- Andrei Alexandrescu (3/19) May 22 2012 Typing must always be sound.
My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));
May 18 2012
On 18-05-2012 20:22, Mehrdad wrote:My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Delegates. Pointer to member function + class instance. -- Alex Rønne Petersen alex lycus.org http://lycus.org
May 18 2012
On 5/18/12 1:22 PM, Mehrdad wrote:My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static. Andrei
May 18 2012
On Friday, 18 May 2012 at 18:30:48 UTC, Andrei Alexandrescu wrote:On 5/18/12 1:22 PM, Mehrdad wrote:Okay I'll report it... hopefully it isn't just with my version though (a little different from official version).My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static. Andrei
May 18 2012
On Friday, 18 May 2012 at 18:32:00 UTC, Mehrdad wrote:Okay I'll report it... hopefully it isn't just with my version though (a little different from official version).http://d.puremagic.com/issues/show_bug.cgi?id=8114
May 18 2012
On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug. The purpose is so you can get the function pointer portion of a delegate without an instance of the object. Possible (obscure) usage: class Test { public void foo() { writeln("foo");} public void bar() { writeln("bar");} } void x(Object context, void function() f1, void function() f2) { void delegate() dg; dg.ptr = cast(void *)context; if(uniform(0, 2)) dg.funcptr = f1; else dg.funcptr = f2; dg(); } void main() { auto t = new Test; x(t, &Test.foo, &Test.bar); } Another interesting usage is to test if a function has been overridden: if((&t.foo).funcptr == &Test.foo) writeln("not overridden!"); I personally think the "feature" is too awkward for any real usage. Someone once suggested funcptr and &Test.foo should return void *, so the addresses could be compared, but not used (it's too easy to call this function). In any case, not a bug. -SteveMy brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.
May 18 2012
On Friday, 18 May 2012 at 18:59:23 UTC, Steven Schveighoffer wrote:On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I actually realized that might be the reason before I reported this, but then I thought: In that case, shouldn't the 'this' parameter be explicitly part of the function (at the end of the parameter list)?On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug. The purpose is so you can get the function pointer portion of a delegate without an instance of the object.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.
May 18 2012
On Fri, 18 May 2012 15:17:28 -0400, Mehrdad <wfunction hotmail.com> wrote:On Friday, 18 May 2012 at 18:59:23 UTC, Steven Schveighoffer wrote:That would be nice, wouldn't it? :) -SteveOn Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I actually realized that might be the reason before I reported this, but then I thought: In that case, shouldn't the 'this' parameter be explicitly part of the function (at the end of the parameter list)?On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug. The purpose is so you can get the function pointer portion of a delegate without an instance of the object.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.
May 18 2012
On 18-05-2012 21:34, Steven Schveighoffer wrote:On Fri, 18 May 2012 15:17:28 -0400, Mehrdad <wfunction hotmail.com> wrote:At least it would prevent writing platform/compiler-specific code... -- Alex Rønne Petersen alex lycus.org http://lycus.orgOn Friday, 18 May 2012 at 18:59:23 UTC, Steven Schveighoffer wrote:That would be nice, wouldn't it? :) -SteveOn Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I actually realized that might be the reason before I reported this, but then I thought: In that case, shouldn't the 'this' parameter be explicitly part of the function (at the end of the parameter list)?On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug. The purpose is so you can get the function pointer portion of a delegate without an instance of the object.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.
May 18 2012
"Mehrdad" <wfunction hotmail.com> wrote in message news:ifswigmcenyryxzyvbpv forum.dlang.org...On Friday, 18 May 2012 at 18:59:23 UTC, Steven Schveighoffer wrote:No, that won't work in all cases due to the ordering of parameters, 'this' and the hidden struct pointer.On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I actually realized that might be the reason before I reported this, but then I thought: In that case, shouldn't the 'this' parameter be explicitly part of the function (at the end of the parameter list)?On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug. The purpose is so you can get the function pointer portion of a delegate without an instance of the object.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.
May 18 2012
On Saturday, 19 May 2012 at 01:37:54 UTC, Daniel Murphy wrote:No, that won't work in all cases due to the ordering of parameters, 'this' and the hidden struct pointer.Better than not working in /any/ cases lol. :P Maybe you can add a void* for the hidden struct parameter? idk...
May 18 2012
"Mehrdad" <wfunction hotmail.com> wrote in message news:sxiwbwuwvcjrlvpfsgpi forum.dlang.org...On Saturday, 19 May 2012 at 01:37:54 UTC, Daniel Murphy wrote:I'd actually rather it /didn't/ work in any cases, and just returned void*. The .funcptr property of delegates too. From what I can tell the main use of this 'feature' is to cause nasty bugs whenever somebody accidentally takes the address of a non-static member function without an instance. Last time I checked, phobos uses this in a couple of places to see if a member function can be called with a specific set of args, but this can be replaced with S.init.func(...). There is an existing bug report for this somewhere.No, that won't work in all cases due to the ordering of parameters, 'this' and the hidden struct pointer.Better than not working in /any/ cases lol. :P Maybe you can add a void* for the hidden struct parameter? idk...
May 18 2012
On Saturday, 19 May 2012 at 02:38:11 UTC, Daniel Murphy wrote:I'd actually rather it /didn't/ work in any cases, and just returned void*.Well if that's an option then I like that too.
May 18 2012
Le 19/05/2012 03:37, Daniel Murphy a écrit :"Mehrdad"<wfunction hotmail.com> wrote in message news:ifswigmcenyryxzyvbpv forum.dlang.org...extern(this) and you are done expressing thiscall.On Friday, 18 May 2012 at 18:59:23 UTC, Steven Schveighoffer wrote:No, that won't work in all cases due to the ordering of parameters, 'this' and the hidden struct pointer.On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I actually realized that might be the reason before I reported this, but then I thought: In that case, shouldn't the 'this' parameter be explicitly part of the function (at the end of the parameter list)?On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug. The purpose is so you can get the function pointer portion of a delegate without an instance of the object.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.
May 19 2012
On 5/18/12 1:59 PM, Steven Schveighoffer wrote:On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:It is.On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.The purpose is so you can get the function pointer portion of a delegate without an instance of the object.Typing is what it is. The following program is unsound without a cast in sight: class Test { void foo() { writeln("foo"); } } static assert(is(typeof(&Test.foo) == void function())); void fun() { writeln("fun"); } void main() { alias void function() TFun; TFun a = &fun; a(); a = &Test.foo; a(); } At best things could be arranged that &Test.foo has type void function(Test) or something. Andrei
May 18 2012
Le 18/05/2012 22:35, Andrei Alexandrescu a écrit :On 5/18/12 1:59 PM, Steven Schveighoffer wrote:It would be nice, but require a way to express that calling convention (thiscall is often different than simply passing an argument). I proposed extern(this). This would have the extra benefice of being able to declare UFCS with thiscall convention. If the extern isn't added, the feature must go, it is made to write bugs.On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:It is.On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.The purpose is so you can get the function pointer portion of a delegate without an instance of the object.Typing is what it is. The following program is unsound without a cast in sight: class Test { void foo() { writeln("foo"); } } static assert(is(typeof(&Test.foo) == void function())); void fun() { writeln("fun"); } void main() { alias void function() TFun; TFun a = &fun; a(); a = &Test.foo; a(); } At best things could be arranged that &Test.foo has type void function(Test) or something. Andrei
May 19 2012
On Fri, 18 May 2012 16:35:38 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 5/18/12 1:59 PM, Steven Schveighoffer wrote:Poor design? Yes. Bug? no. It's behavior is very intentional and has been discussed several times over the last several years. It's existed before D2 was even branched, at least since I learned D in 2007.On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:It is.On 5/18/12 1:22 PM, Mehrdad wrote:No, this is not a bug.My brain just exploded. Can someone explain what's going on? class Test { public void foo() { } } static assert(is(typeof(&Test.foo) == void function()));Looks like a bug. The assert should pass only if foo were static.I agree, it's unsound. But so is this: int *blah = void; *blah = 5; It doesn't mean that the language should forbid it, or that the compiler isn't implemented as designed. At the *very least*, the address to member function operation should be illegal in safe code.The purpose is so you can get the function pointer portion of a delegate without an instance of the object.Typing is what it is. The following program is unsound without a cast in sight: class Test { void foo() { writeln("foo"); } } static assert(is(typeof(&Test.foo) == void function())); void fun() { writeln("fun"); } void main() { alias void function() TFun; TFun a = &fun; a(); a = &Test.foo; a(); }At best things could be arranged that &Test.foo has type void function(Test) or something.I would suggest that it should be: function(Test this) with the 'this' being mangled into the name, and affect the calling convention. Structs would be function(ref Test this). And const/shared/immutable decorations should apply properly to the 'this' parameter. I'd wholeheartedly support such an improvement. In fact, I'd be willing to write a DIP on it, if Walter had a chance of approving it. I just don't know if it would happen... -Steve
May 22 2012
On 2012-05-22 20:14, Steven Schveighoffer wrote:I agree, it's unsound. But so is this: int *blah = void; *blah = 5; It doesn't mean that the language should forbid it, or that the compiler isn't implemented as designed. At the *very least*, the address to member function operation should be illegal in safe code.It needs to be possible to compose delegates: class Foo { void foo () {}; } void delegate () dg; dg.funcptr = &Foo.foo; dg.ptr = cast(void*) new Foo; dg(); At least it needs to be possible to do that in code marked with system. -- /Jacob CarlborgAt best things could be arranged that &Test.foo has type void function(Test) or something.I would suggest that it should be: function(Test this) with the 'this' being mangled into the name, and affect the calling convention. Structs would be function(ref Test this). And const/shared/immutable decorations should apply properly to the 'this' parameter. I'd wholeheartedly support such an improvement. In fact, I'd be willing to write a DIP on it, if Walter had a chance of approving it. I just don't know if it would happen... -Steve
May 22 2012
On Tue, 22 May 2012 14:28:33 -0400, Jacob Carlborg <doob me.com> wrote:On 2012-05-22 20:14, Steven Schveighoffer wrote:Error, cannot cast function of type void function(Foo this) to void function(void *this) dg.funcptr = cast(void function(void *this))&Foo.foo; // okI would suggest that it should be: function(Test this) with the 'this' being mangled into the name, and affect the calling convention. Structs would be function(ref Test this). And const/shared/immutable decorations should apply properly to the 'this' parameter. I'd wholeheartedly support such an improvement. In fact, I'd be willing to write a DIP on it, if Walter had a chance of approving it. I just don't know if it would happen...It needs to be possible to compose delegates: class Foo { void foo () {}; } void delegate () dg; dg.funcptr = &Foo.foo;dg.ptr = cast(void*) new Foo; dg(); At least it needs to be possible to do that in code marked with system.I think it should require a cast, regardless of the system attribute, you are telling the type system a function that requires a Foo is now OK to accept a void *. I don't think that's something we should accept implicitly. -Steve
May 22 2012
On 2012-05-22 20:35, Steven Schveighoffer wrote:I have no problem with a couple of case, as long as it's possible to compose delegates as above. The example was just how it works today, and an explanation of what I meant by "composing delegates". This can be of great help when interfacing with other language. I used this technique to call D methods from Objective-C. -- /Jacob CarlborgIt needs to be possible to compose delegates: class Foo { void foo () {}; } void delegate () dg; dg.funcptr = &Foo.foo;Error, cannot cast function of type void function(Foo this) to void function(void *this) dg.funcptr = cast(void function(void *this))&Foo.foo; // okdg.ptr = cast(void*) new Foo; dg(); At least it needs to be possible to do that in code marked with system.I think it should require a cast, regardless of the system attribute, you are telling the type system a function that requires a Foo is now OK to accept a void *. I don't think that's something we should accept implicitly. -Steve
May 22 2012
On 5/22/12 1:14 PM, Steven Schveighoffer wrote:I agree, it's unsound. But so is this: int *blah = void; *blah = 5; It doesn't mean that the language should forbid it, or that the compiler isn't implemented as designed.Initialization with void is a feature. My example shows the fail of a feature. There is no comparison.At the *very least*, the address to member function operation should be illegal in safe code.It should be verboten. Other means should be devised for achieving whatever utility is there.Very reasonable. Walter, could you please weigh in on this. Thanks, AndreiAt best things could be arranged that &Test.foo has type void function(Test) or something.I would suggest that it should be: function(Test this) with the 'this' being mangled into the name, and affect the calling convention. Structs would be function(ref Test this). And const/shared/immutable decorations should apply properly to the 'this' parameter. I'd wholeheartedly support such an improvement. In fact, I'd be willing to write a DIP on it, if Walter had a chance of approving it. I just don't know if it would happen...
May 22 2012
On Tue, 22 May 2012 15:29:10 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 5/22/12 1:14 PM, Steven Schveighoffer wrote:Your example shows an invalid use for a feature. There are valid uses for that feature that are not unsound. But I think we are on the same page -- the misfeature is not that you *can* take a member address, it's the *type* that it is given.I agree, it's unsound. But so is this: int *blah = void; *blah = 5; It doesn't mean that the language should forbid it, or that the compiler isn't implemented as designed.Initialization with void is a feature. My example shows the fail of a feature. There is no comparison.I agree, the feature is prone to error. -SteveAt the *very least*, the address to member function operation should be illegal in safe code.It should be verboten. Other means should be devised for achieving whatever utility is there.
May 22 2012
On 5/22/12 4:05 PM, Steven Schveighoffer wrote:On Tue, 22 May 2012 15:29:10 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Typing must always be sound. AndreiOn 5/22/12 1:14 PM, Steven Schveighoffer wrote:Your example shows an invalid use for a feature. There are valid uses for that feature that are not unsound.I agree, it's unsound. But so is this: int *blah = void; *blah = 5; It doesn't mean that the language should forbid it, or that the compiler isn't implemented as designed.Initialization with void is a feature. My example shows the fail of a feature. There is no comparison.
May 22 2012