digitalmars.D - Property assignment problem
- SebastianA (40/40) May 10 2012 This is related to this thread:
- Jonathan M Davis (13/59) May 11 2012 Remove the ref from the setter. Either that or duplicate it:
- SebastianA (7/76) May 11 2012 Okay, thanks for the info. The weird thing is, if I change the
- Jonathan M Davis (7/15) May 11 2012 struct literals work. They at least used to be lvalues for some bizarre
- SebastianA (12/31) May 11 2012 I did this very naive test:
- Iain Buclaw (9/40) May 11 2012 The copy of GDC you have is probably on build 2.057 - two releases
- Jacob Carlborg (4/10) May 11 2012 Why would the ternary operator make any difference?
- kenji hara (11/24) May 11 2012 Just before the release of 2.059, I implemented the behavior to avoid
- Manu (21/30) May 11 2012 Yeah, I've run into a need for 'auto ref' a few times now actually, and
- travert phare.normalesup.org (Christophe) (2/7) May 11 2012
- Manu (2/8) May 11 2012 Indeed, and vice versa.
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 Friday, 11 May 2012 at 07:03:10 UTC, Jonathan M Davis wrote:On Friday, May 11, 2012 08:52:14 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?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 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: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 AhlmanOkay, 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 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: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';On Friday, May 11, 2012 09:10:37 SebastianA wrote: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.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 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 DavisWhy would the ternary operator make any difference? -- /Jacob Carlborg
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 DavisWhy would the ternary operator make any difference? -- /Jacob Carlborg
May 11 2012
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?
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 11 May 2012 13:21, Christophe <travert phare.normalesup.org> wrote:Manu , dans le message (digitalmars.D:166891), a =C3=A9crit :Indeed, and vice versa.All ref should really be, is syntactical sugar for a pointer, whichassertsthat it be non-null/initialised, and that it not expose the pointer assignment mechanism.And implicit conversion of l-values to their ref type.
May 11 2012