digitalmars.D - Property assignment problem
- "SebastianA" <sebastian.ahlman remedygames.com> May 10 2012
- Jonathan M Davis <jmdavisProg gmx.com> May 11 2012
- Jacob Carlborg <doob me.com> May 11 2012
- travert phare.normalesup.org (Christophe) May 11 2012
- "SebastianA" <sebastian.ahlman remedygames.com> May 11 2012
- Jonathan M Davis <jmdavisProg gmx.com> May 11 2012
- "SebastianA" <sebastian.ahlman remedygames.com> May 11 2012
- Iain Buclaw <ibuclaw ubuntu.com> May 11 2012
- kenji hara <k.hara.pg gmail.com> May 11 2012
- Manu <turkeyman gmail.com> May 11 2012
- Manu <turkeyman gmail.com> May 11 2012
This is related to this thread: http://forum.dlang.org/thread/cnwpmhihmckpjhlaszzy forum.dlang.org I am posting it here as well, since it no longer concerns only GDC. Also, I am not sure if this is a bug or intended behaviour. Consider the following code: ==== void runTest() { Thing t; t.vPosition = (Clock.currStdTime % 2 == 0) ? Vec(2, 2) : Vec(3, 3); Vec v = t.vPosition; writefln("%d %d\n", v.x, v.y); } struct Vec { int x; int y; } struct Thing { property Vec vPosition() { return mPosition; } property Vec vPosition( const ref Vec value ) { return mPosition = value; } private: Vec mPosition; } ==== The line that sets the value of the vPosition property does not compile on DMD. Instead it gives the error "Error: not a property t.vPosition". On GDC this compiles but it does not work in release mode, only in debug mode. In release mode it sets the property to 0 0. If I assign the vector to a temp variable before assigning it to the position it works. It also works if I replace the time expression with a constant like "true" or some other value known at compile time. Is this a bug or is it supposed to refuse to compile the code? Also, why does it compile on GDC? BR, Sebastian Ahlman
May 10 2012
On Friday, May 11, 2012 08:52:14 SebastianA wrote:This is related to this thread: http://forum.dlang.org/thread/cnwpmhihmckpjhlaszzy forum.dlang.org I am posting it here as well, since it no longer concerns only GDC. Also, I am not sure if this is a bug or intended behaviour. Consider the following code: ==== void runTest() { Thing t; t.vPosition = (Clock.currStdTime % 2 == 0) ? Vec(2, 2) : Vec(3, 3); Vec v = t.vPosition; writefln("%d %d\n", v.x, v.y); } struct Vec { int x; int y; } struct Thing { property Vec vPosition() { return mPosition; } property Vec vPosition( const ref Vec value ) { return mPosition = value; } private: Vec mPosition; } ==== The line that sets the value of the vPosition property does not compile on DMD. Instead it gives the error "Error: not a property t.vPosition". On GDC this compiles but it does not work in release mode, only in debug mode. In release mode it sets the property to 0 0. If I assign the vector to a temp variable before assigning it to the position it works. It also works if I replace the time expression with a constant like "true" or some other value known at compile time. Is this a bug or is it supposed to refuse to compile the code? Also, why does it compile on GDC?
Remove the ref from the setter. Either that or duplicate it: property Vec vPosition( const Vec value ) { return mPosition = value; } property Vec vPosition( const ref Vec value ) { return mPosition = value; } ref does not currently accept rvalues, even if it's const (unlike C++). There are issues in C++ caused by the fact that const& parameters can be either lvalues or rvalues, so D insists that ref is always an lvalue, even if it's const. There has been some discussion of making it possible for ref and const ref to take rvalues with some set of restrictions to avoid the problems that it causes in C++, but that hasn't been fully sorted out yet. - Jonathan M Davis
May 11 2012
On 2012-05-11 09:18, Jonathan M Davis wrote:struct literals work. They at least used to be lvalues for some bizarre reason. I'm not sure if they are now, because it went back and forth prior to the last release. They're either still lvalues or the first part of making rvalues work with ref has been implemented (but only with struct literals). I'm not sure which. - Jonathan M Davis
Why would the ternary operator make any difference? -- /Jacob Carlborg
May 11 2012
Manu , dans le message (digitalmars.D:166891), a écrit :All ref should really be, is syntactical sugar for a pointer, which asserts that it be non-null/initialised, and that it not expose the pointer assignment mechanism.
And implicit conversion of l-values to their ref type.Is there something more that 'ref' does in D that wouldn't work under that setup?
May 11 2012
On Friday, 11 May 2012 at 07:03:10 UTC, Jonathan M Davis wrote:On Friday, May 11, 2012 08:52:14 SebastianA wrote:This is related to this thread: http://forum.dlang.org/thread/cnwpmhihmckpjhlaszzy forum.dlang.org I am posting it here as well, since it no longer concerns only GDC. Also, I am not sure if this is a bug or intended behaviour. Consider the following code: ==== void runTest() { Thing t; t.vPosition = (Clock.currStdTime % 2 == 0) ? Vec(2, 2) : Vec(3, 3); Vec v = t.vPosition; writefln("%d %d\n", v.x, v.y); } struct Vec { int x; int y; } struct Thing { property Vec vPosition() { return mPosition; } property Vec vPosition( const ref Vec value ) { return mPosition = value; } private: Vec mPosition; } ==== The line that sets the value of the vPosition property does not compile on DMD. Instead it gives the error "Error: not a property t.vPosition". On GDC this compiles but it does not work in release mode, only in debug mode. In release mode it sets the property to 0 0. If I assign the vector to a temp variable before assigning it to the position it works. It also works if I replace the time expression with a constant like "true" or some other value known at compile time. Is this a bug or is it supposed to refuse to compile the code? Also, why does it compile on GDC?
Remove the ref from the setter. Either that or duplicate it: property Vec vPosition( const Vec value ) { return mPosition = value; } property Vec vPosition( const ref Vec value ) { return mPosition = value; } ref does not currently accept rvalues, even if it's const (unlike C++). There are issues in C++ caused by the fact that const& parameters can be either lvalues or rvalues, so D insists that ref is always an lvalue, even if it's const. There has been some discussion of making it possible for ref and const ref to take rvalues with some set of restrictions to avoid the problems that it causes in C++, but that hasn't been fully sorted out yet. - Jonathan M Davis
Okay, thanks for the info. The weird thing is, if I change the line to: t.vPosition = Vec(2, 2); it compiles and works, even if the property is ref. As far as I know, this does nothing towards correcting the rvalue issue. Should this also cause an error?
May 11 2012
On Friday, May 11, 2012 09:10:37 SebastianA wrote:Okay, thanks for the info. The weird thing is, if I change the line to: t.vPosition = Vec(2, 2); it compiles and works, even if the property is ref. As far as I know, this does nothing towards correcting the rvalue issue. Should this also cause an error?
struct literals work. They at least used to be lvalues for some bizarre reason. I'm not sure if they are now, because it went back and forth prior to the last release. They're either still lvalues or the first part of making rvalues work with ref has been implemented (but only with struct literals). I'm not sure which. - Jonathan M Davis
May 11 2012
On Friday, 11 May 2012 at 07:18:30 UTC, Jonathan M Davis wrote:On Friday, May 11, 2012 09:10:37 SebastianA wrote:Okay, thanks for the info. The weird thing is, if I change the line to: t.vPosition = Vec(2, 2); it compiles and works, even if the property is ref. As far as I know, this does nothing towards correcting the rvalue issue. Should this also cause an error?
struct literals work. They at least used to be lvalues for some bizarre reason. I'm not sure if they are now, because it went back and forth prior to the last release. They're either still lvalues or the first part of making rvalues work with ref has been implemented (but only with struct literals). I'm not sure which. - Jonathan M Davis
I did this very naive test: "Vec(2, 2) = Vec(3, 4);" which gave me the error "test.d(30): Error: Vec(2,2) is not an lvalue" so apparently it's not an lvalue, at least not in that sense. Anyway, thanks for the info. We can probably get around the problem by using non-ref parameters for now. It is very weird that GDC accepts the code though, and it even works when running a debug build. BR, Sebastian Ahlman
May 11 2012
On 11 May 2012 08:26, SebastianA <sebastian.ahlman remedygames.com> wrote:On Friday, 11 May 2012 at 07:18:30 UTC, Jonathan M Davis wrote:On Friday, May 11, 2012 09:10:37 SebastianA wrote:Okay, thanks for the info. The weird thing is, if I change the line to: t.vPosition = Vec(2, 2); it compiles and works, even if the property is ref. As far as I know, this does nothing towards correcting the rvalue issue. Should this also cause an error?
struct literals work. They at least used to be lvalues for some bizarre reason. I'm not sure if they are now, because it went back and forth prior to the last release. They're either still lvalues or the first part of making rvalues work with ref has been implemented (but only with struct literals). I'm not sure which. - Jonathan M Davis
I did this very naive test: "Vec(2, 2) = Vec(3, 4);" which gave me the error "test.d(30): Error: Vec(2,2) is not an lvalue" so apparently it's not an lvalue, at least not in that sense. Anyway, thanks for the info. We can probably get around the problem by using non-ref parameters for now. It is very weird that GDC accepts the code though, and it even works when running a debug build.
The copy of GDC you have is probably on build 2.057 - two releases behind the current language implementation. I have been testing your example on my development tree, and can't reproduce the issue of it returning (0,0) after the ternary assignment - though it does compile fine. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
May 11 2012
Just before the release of 2.059, I implemented the behavior to avoid breaking of existing codes for only struct literals. I didn't support other rvalues with it, like such ternary expression. It was minimum hack. I think it is a special behavior of 2.059, and I've been highly skeptical to leave it up to the future, even if changing it breaks existing codes. I also think that a need of 'auto ref stroage class for non-template function parameter' is increasing. Kenji Hara 2012/5/11 Jacob Carlborg <doob me.com>:On 2012-05-11 09:18, Jonathan M Davis wrote:struct literals work. They at least used to be lvalues for some bizarre reason. I'm not sure if they are now, because it went back and forth prior to the last release. They're either still lvalues or the first part of making rvalues work with ref has been implemented (but only with struct literals). I'm not sure which. - Jonathan M Davis
Why would the ternary operator make any difference? -- /Jacob Carlborg
May 11 2012
--20cf3074d25c53865104bfbf9c88 Content-Type: text/plain; charset=UTF-8 On 11 May 2012 11:24, kenji hara <k.hara.pg gmail.com> wrote:Just before the release of 2.059, I implemented the behavior to avoid breaking of existing codes for only struct literals. I didn't support other rvalues with it, like such ternary expression. It was minimum hack. I think it is a special behavior of 2.059, and I've been highly skeptical to leave it up to the future, even if changing it breaks existing codes. I also think that a need of 'auto ref stroage class for non-template function parameter' is increasing.
Yeah, I've run into a need for 'auto ref' a few times now actually, and I've also been running into these lvalue->ref problems all week. What are the odds that full const ref support might be fleshed out some time soon? We're having to implement quite a few work around for it... This problem has gotten me thinking though, should ref just be a proper storage class? (why isn't it?) It seems that would address almost all problems with it immediately. - There are also some syntactical issues/ambiguities that ref(type) would solve. - You'd be able to declare ref locals (which would be super useful) - 'auto' would work, no need to special case said 'ref auto', which seems a but nasty, in generic code you might not always want that... It'll only be a matter of days before someone wants a 'true' auto. - Solve these recently discussed issues where you can't describe a function/delegate that returns by ref without piping it through an alias. All ref should really be, is syntactical sugar for a pointer, which asserts that it be non-null/initialised, and that it not expose the pointer assignment mechanism. Is there something more that 'ref' does in D that wouldn't work under that setup? --20cf3074d25c53865104bfbf9c88 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 11 May 2012 11:24, kenji hara <span dir=3D"lt= r"><<a href=3D"mailto:k.hara.pg gmail.com" target=3D"_blank">k.hara.pg g= mail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style= =3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Just before the release of 2.059, I implemented the behavior to avoid<br> breaking of existing codes for only struct literals. I didn't support<b= r> other rvalues with it, like such ternary expression. It was minimum<br> hack.<br> <br> I think it is a special behavior of 2.059, and I've been highly<br> skeptical to leave it up to the future, even if changing it breaks<br> existing codes.<br> <br> I also think that a need of 'auto ref stroage class for non-template<br=
Yeah, I've run into a need for 'auto ref' a few times now actua= lly, and I've also been running into these lvalue->ref problems all = week.</div> <div>What are the odds that full const ref support might be fleshed out som= e time soon? We're having to implement quite a few work around for it..= .</div><div><br></div><div>This problem has gotten me thinking though, shou= ld ref just be a proper storage class? (why isn't it?)</div> <div>It seems that would address almost all problems with it immediately.</= div><div>=C2=A0 - There are also some syntactical issues/ambiguities that r= ef(type) would solve.</div><div>=C2=A0 - You'd be able to declare ref l= ocals (which would be super useful)</div> <div>=C2=A0 - 'auto' would work, no need to special case said '= ref auto', which seems a but nasty, in generic code you might not alway= s want that... It'll only be a matter of days before someone wants a &#= 39;true' auto.</div> <div>=C2=A0 - Solve these recently discussed issues where you can't des= cribe a function/delegate that returns by ref without piping it through an = alias.</div><div><br></div><div>All ref should really be, is syntactical su= gar for a pointer, which asserts that it be non-null/initialised, and that = it not expose the pointer assignment mechanism.</div> <div>Is there something more that 'ref' does in D that wouldn't= work under that setup?</div></div> --20cf3074d25c53865104bfbf9c88--
May 11 2012
--20cf300fb0c752a22004bfc2bc28 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 11 May 2012 13:21, Christophe <travert phare.normalesup.org> wrote:Manu , dans le message (digitalmars.D:166891), a =C3=A9crit :All ref should really be, is syntactical sugar for a pointer, which
that it be non-null/initialised, and that it not expose the pointer assignment mechanism.
And implicit conversion of l-values to their ref type.
Indeed, and vice versa. --20cf300fb0c752a22004bfc2bc28 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 11 May 2012 13:21, Christophe <span dir=3D"lt= r"><<a href=3D"mailto:travert phare.normalesup.org" target=3D"_blank">tr= avert phare.normalesup.org</a>></span> wrote:<br><blockquote class=3D"gm= ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le= ft:1ex"> Manu , dans le message (digitalmars.D:166891), a =C3=A9crit=C2=A0:<br> <div class=3D"im">> All ref should really be, is syntactical sugar for a= pointer, which asserts<br> > that it be non-null/initialised, and that it not expose the pointer<br=
<br> </div>And implicit conversion of l-values to their ref type.</blockquote><d= iv><br></div><div>Indeed, and vice versa.</div></div> --20cf300fb0c752a22004bfc2bc28--
May 11 2012









travert phare.normalesup.org (Christophe) 