Jump to page: 1 2
Thread overview
Property assignment problem
May 11, 2012
SebastianA
May 11, 2012
Jonathan M Davis
May 11, 2012
SebastianA
May 11, 2012
Jonathan M Davis
May 11, 2012
SebastianA
May 11, 2012
Iain Buclaw
May 11, 2012
Jacob Carlborg
May 11, 2012
kenji hara
May 11, 2012
Manu
May 11, 2012
Christophe
May 11, 2012
Manu
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 11, 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:
>> 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 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
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
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?
« First   ‹ Prev
1 2