Thread overview | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 25, 2005 Method resolution sucks | ||||
---|---|---|---|---|
| ||||
As many of you know, I have a certain distaste for the D method-resolution imlementation. This example is one of many that I feel justifies that distaste: We have a method foo: uint foo (inout int x) {return 0;} and we have a caller bar: void bar() { uint y; foo (y); } Compiler says "cast(uint)(x) is not an lvalue" -- referring to the invocation of foo(y) Fair enough. Implicit conversion is another issue altogether, so we'll add another foo() method to handle the alternate argument type: uint foo (inout int x) {return 0;} uint foo (inout uint x) {return 0;} void wumpus() { uint y; return foo(y); } Compiler says "function foo overloads uint(inout uint x) and uint(inout int x) both match argument list for foo" -- again, for the invocation of foo(y). You get the drift of that? Note, of course, that one cannot even think about typecasting with inout/reference arguments ~ that's yet another dead-end issue. The whole arena of method resolution (when combined with implicit typecasting, pass by reference, overloading, etc) is about as bulletproof as a torn t-shirt. Please try to do something about this, Walter. |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | On Fri, 25 Feb 2005 03:34:18 +0000 (UTC), Kris wrote: > As many of you know, I have a certain distaste for the D method-resolution imlementation. This example is one of many that I feel justifies that distaste: > > We have a method foo: > > uint foo (inout int x) {return 0;} > > and we have a caller bar: > > void bar() > { > uint y; > > foo (y); > } > > Compiler says "cast(uint)(x) is not an lvalue" -- referring to the invocation of > foo(y) > > Fair enough. Implicit conversion is another issue altogether, so we'll add another foo() method to handle the alternate argument type: > > uint foo (inout int x) {return 0;} > uint foo (inout uint x) {return 0;} > > void wumpus() > { > uint y; > > return foo(y); > } > > Compiler says "function foo overloads uint(inout uint x) and uint(inout int x) > both match argument list for foo" -- again, for the invocation of foo(y). > > You get the drift of that? > > Note, of course, that one cannot even think about typecasting with inout/reference arguments ~ that's yet another dead-end issue. > > The whole arena of method resolution (when combined with implicit typecasting, pass by reference, overloading, etc) is about as bulletproof as a torn t-shirt. > > Please try to do something about this, Walter. Sorry, Kris, but I'm not getting any errors here, except that your example function 'wumpus()' returns a void. Once I changed that to a uint it compiled fine. Windows v0.113 <code> uint foo (inout int x) {return 0;} uint foo (inout uint x) {return 0;} uint wumpus() { uint y; return foo(y); } </code> -- Derek Melbourne, Australia 25/02/2005 2:48:33 PM |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <1vsrqzrq891rl$.heltnytmakww.dlg@40tude.net>, Derek Parnell says... > >Sorry, Kris, but I'm not getting any errors here, except that your example function 'wumpus()' returns a void. Once I changed that to a uint it compiled fine. Windows v0.113 This is bizarre. Ignoring the typo's (from writing whilst on the phone), the snippet was intended to represent the real thing. But I cannot get this to fail in an islolated test-case either! Even when I copy out the original code, try two modules instead of one, change the order of declaration, and so on. Yet the problem persists in the original code; Something smells a bit fishy. |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <1vsrqzrq891rl$.heltnytmakww.dlg@40tude.net>, Derek Parnell says... >Sorry, Kris, but I'm not getting any errors here, except that your example function 'wumpus()' returns a void. Once I changed that to a uint it compiled fine. Windows v0.113 > ><code> >uint foo (inout int x) {return 0;} >uint foo (inout uint x) {return 0;} > >uint wumpus() >{ >uint y; > >return foo(y); >} ></code> OK ~ found out what actually breaks: uint foo (char[] s, inout int v, uint r=10) {return 0;} uint foo (char[] s, inout uint v, uint r=10) {return 0;} void bar() { char[] s; int c; foo (s, c); // compiles foo (s, c, 12); // fails } There's some kind of issue with the default assignment ... yet the error message states "cast(uint)(c) is not an lvalue", along with the other msg about "both match argument list" Again; about as bulletproof as a broken-window |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | On Fri, 25 Feb 2005 05:16:31 +0000 (UTC), Kris wrote: > uint foo (char[] s, inout int v, uint r=10) {return 0;} > uint foo (char[] s, inout uint v, uint r=10) {return 0;} > > void bar() > { > char[] s; > int c; > > foo (s, c); // compiles > foo (s, c, 12); // fails > } Yep, you've tripped up on the unexpected implicit conversion of literals. Try ... foo (s, c, 12U); // Force it to use an unsigned literal. -- Derek Melbourne, Australia 25/02/2005 4:22:45 PM |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <ztzjyq7wiz1e$.1e67b7jjrdwpz.dlg@40tude.net>, Derek Parnell says... > >On Fri, 25 Feb 2005 05:16:31 +0000 (UTC), Kris wrote: > >> uint foo (char[] s, inout int v, uint r=10) {return 0;} >> uint foo (char[] s, inout uint v, uint r=10) {return 0;} >> >> void bar() >> { >> char[] s; >> int c; >> >> foo (s, c); // compiles >> foo (s, c, 12); // fails >> } > >Yep, you've tripped up on the unexpected implicit conversion of literals. > >Try ... > > foo (s, c, 12U); // Force it to use an unsigned literal. Oof ... that shows just how fragile it truly is. The '12' will always be implicity cast anyway (given the current scheme of things), yet it breaks in this particular case with an error on the argument 'c' instead ~ great. Can we expect a fix for this please, Walter? |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | "Kris" <Kris_member@pathlink.com> wrote in message news:cvme71$2svv$1@digitaldaemon.com... > In article <ztzjyq7wiz1e$.1e67b7jjrdwpz.dlg@40tude.net>, Derek Parnell says... >> >>On Fri, 25 Feb 2005 05:16:31 +0000 (UTC), Kris wrote: >> >>> uint foo (char[] s, inout int v, uint r=10) {return 0;} >>> uint foo (char[] s, inout uint v, uint r=10) {return 0;} >>> >>> void bar() >>> { >>> char[] s; >>> int c; >>> >>> foo (s, c); // compiles >>> foo (s, c, 12); // fails >>> } >> >>Yep, you've tripped up on the unexpected implicit conversion of literals. >> >>Try ... >> >> foo (s, c, 12U); // Force it to use an unsigned literal. > > > Oof ... that shows just how fragile it truly is. The '12' will always be > implicity cast anyway (given the current scheme of things), yet it breaks > in > this particular case with an error on the argument 'c' instead ~ great. > > Can we expect a fix for this please, Walter? > I don't have an opinion about what the behavior should be but in any case the help in http://www.digitalmars.com/d/function.html#overloading could use some more details and/or examples. An example of where "multiple matches with implicit conversions" can come up would be nice. eg: void foo(int v, uint r) { } void foo(uint v, int r) { } void bar() { foo(10,10); } // doesn't compile multiple match another example void foo(int v, uint r) { } void foo(uint v, char[] r) { } void bar() { foo(10,"hello"); } // does compile another example void foo(int v, uint r) { } void foo(uint v, uint r) { } void bar() { foo(10,10); } // doesn't compile multiple match - should it? |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | In article <cvngu1$uvm$1@digitaldaemon.com>, Ben Hinkle says... > > >"Kris" <Kris_member@pathlink.com> wrote in message news:cvme71$2svv$1@digitaldaemon.com... >> In article <ztzjyq7wiz1e$.1e67b7jjrdwpz.dlg@40tude.net>, Derek Parnell says... >>> >>>On Fri, 25 Feb 2005 05:16:31 +0000 (UTC), Kris wrote: >>> >>>> uint foo (char[] s, inout int v, uint r=10) {return 0;} >>>> uint foo (char[] s, inout uint v, uint r=10) {return 0;} >>>> >>>> void bar() >>>> { >>>> char[] s; >>>> int c; >>>> >>>> foo (s, c); // compiles >>>> foo (s, c, 12); // fails >>>> } >>> >>>Yep, you've tripped up on the unexpected implicit conversion of literals. >>> >>>Try ... >>> >>> foo (s, c, 12U); // Force it to use an unsigned literal. >> >> >> Oof ... that shows just how fragile it truly is. The '12' will always be >> implicity cast anyway (given the current scheme of things), yet it breaks >> in >> this particular case with an error on the argument 'c' instead ~ great. >> >> Can we expect a fix for this please, Walter? >> > >I don't have an opinion about what the behavior should be but in any case the help in http://www.digitalmars.com/d/function.html#overloading could use some more details and/or examples. An example of where "multiple matches with implicit conversions" can come up would be nice. eg: > > void foo(int v, uint r) { } > void foo(uint v, int r) { } > void bar() { foo(10,10); } // doesn't compile multiple match > >another example > void foo(int v, uint r) { } > void foo(uint v, char[] r) { } > void bar() { foo(10,"hello"); } // does compile > >another example > void foo(int v, uint r) { } > void foo(uint v, uint r) { } > void bar() { foo(10,10); } // doesn't compile multiple match - should it? > > You're right, Ben. The documentation could always be better. This is not a case of documentation though, so you might have misread the thread. To reiterate, there's a bug in the signature-matching algorithm whereby it gets hopelessly confused by the prior example; and emits an error that is both thoroughly misleading and confounding. It doesn't complain about literal-number type mismatches ... instead it whines about the preceding argument of a reference type, which would otherwise be acceptable. Your examples above are great, but they are not quite representative of the issue spawning this thread. Again, here is the issue: void foo (inout int x, uint y = 10){} void foo (inout uint x, uint y = 10){} void bar() { int x; foo (x); // good foo (x, 0); // fails, with error on type of 'x', and multiple sig match } As you can see, there's no possible confusion over the type of 'y' -- they're both of type 'uint'. Yet the complier error points at a problem with 'x'. Bork. Bork. The number of errors is dependent upon order of foo() declarations. I'm a bit surprised no-one else seems to have posted about this in the past. |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | "Kris" <Kris_member@pathlink.com> wrote in message news:cvnq8n$18lj$1@digitaldaemon.com... > In article <cvngu1$uvm$1@digitaldaemon.com>, Ben Hinkle says... >> >> >>"Kris" <Kris_member@pathlink.com> wrote in message news:cvme71$2svv$1@digitaldaemon.com... >>> In article <ztzjyq7wiz1e$.1e67b7jjrdwpz.dlg@40tude.net>, Derek Parnell says... >>>> >>>>On Fri, 25 Feb 2005 05:16:31 +0000 (UTC), Kris wrote: >>>> >>>>> uint foo (char[] s, inout int v, uint r=10) {return 0;} >>>>> uint foo (char[] s, inout uint v, uint r=10) {return 0;} >>>>> >>>>> void bar() >>>>> { >>>>> char[] s; >>>>> int c; >>>>> >>>>> foo (s, c); // compiles >>>>> foo (s, c, 12); // fails >>>>> } >>>> >>>>Yep, you've tripped up on the unexpected implicit conversion of literals. >>>> >>>>Try ... >>>> >>>> foo (s, c, 12U); // Force it to use an unsigned literal. >>> >>> >>> Oof ... that shows just how fragile it truly is. The '12' will always be >>> implicity cast anyway (given the current scheme of things), yet it >>> breaks >>> in >>> this particular case with an error on the argument 'c' instead ~ great. >>> >>> Can we expect a fix for this please, Walter? >>> >> >>I don't have an opinion about what the behavior should be but in any case >>the help in http://www.digitalmars.com/d/function.html#overloading could >>use >>some more details and/or examples. An example of where "multiple matches >>with implicit conversions" can come up would be nice. eg: >> >> void foo(int v, uint r) { } >> void foo(uint v, int r) { } >> void bar() { foo(10,10); } // doesn't compile multiple match >> >>another example >> void foo(int v, uint r) { } >> void foo(uint v, char[] r) { } >> void bar() { foo(10,"hello"); } // does compile >> >>another example >> void foo(int v, uint r) { } >> void foo(uint v, uint r) { } >> void bar() { foo(10,10); } // doesn't compile multiple match - should >> it? >> >> > > > You're right, Ben. The documentation could always be better. This is not a > case > of documentation though, so you might have misread the thread. > > To reiterate, there's a bug in the signature-matching algorithm whereby it > gets > hopelessly confused by the prior example; and emits an error that is both > thoroughly misleading and confounding. It doesn't complain about > literal-number > type mismatches ... instead it whines about the preceding argument of a > reference type, which would otherwise be acceptable. Your examples above > are > great, but they are not quite representative of the issue spawning this > thread. > Again, here is the issue: > > void foo (inout int x, uint y = 10){} > void foo (inout uint x, uint y = 10){} > > void bar() > { > int x; > > foo (x); // good > > foo (x, 0); // fails, with error on type of 'x', and multiple sig match > } > > As you can see, there's no possible confusion over the type of 'y' -- > they're > both of type 'uint'. Yet the complier error points at a problem with 'x'. > Bork. > Bork. The number of errors is dependent upon order of foo() declarations. > > I'm a bit surprised no-one else seems to have posted about this in the past. > > Hmm. The error message I got (and I just tried with the reposted example) is just the multiple match error. I stored the code above in test.d and ran dmd test.d on Windows: D:\d>dmd test.d test.d(10): function test.foo overloads void(inout int x,uint y = cast(uint)(10)) and void(inout uint x,uint y = cast(uint)(10)) both match argument list for foo Anyway, I don't really get it so I'll stop confusing the issue any more than I already have... :-P |
February 25, 2005 Re: Method resolution sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | In article <cvnt5c$1bre$1@digitaldaemon.com>, Ben Hinkle says... > > >"Kris" <Kris_member@pathlink.com> wrote in message >> Bork. The number of errors is dependent upon order of foo() declarations. > >Hmm. The error message I got (and I just tried with the reposted example) is just the multiple match error. That's due to the order of foo() declarations, as noted above. Switch them around (or change x from uint to int; or vice versa) and you'll get the "cast(type)(x) not an lvalue" as well. |
Copyright © 1999-2021 by the D Language Foundation