www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ref for (const) variables

reply "Namespace" <rswhite4 gmail.com> writes:
Currently, if you want to store a long getter into a variable 
without copying it (because it may be a big struct), your only 
way is to store it as a pointer:

----
struct Matrix {
     float[16] values= [
         1, 0, 0, 0,
         0, 1, 0, 0,
         0, 0, 1, 0,
         0, 0, 0, 1
     ];
}

struct Test {
private:
     Matrix _matrix;

public:
     ref const(Matrix) getCurrentModelViewMatrix() const pure 
nothrow {
         return _matrix;
     }
}

void main() {
     Test t;

     const(Matrix)* m = &t.getCurrentModelViewMatrix(); // 
currently
}
----

But IMO it would be a lot nicer if I could store the reference 
like this:
----
ref const(Matrix) m = t.getCurrentModelViewMatrix(); // nicer
----

[Of course the name is exaggerated for the purpose of 
demonstration.]

May this be worth of an enhancement request? Or was this already 
rejected?
And, no, I want no mutable references such as C++.
Mar 16 2015
next sibling parent reply "anonymous" <anonymous example.com> writes:
On Monday, 16 March 2015 at 18:47:00 UTC, Namespace wrote:
     const(Matrix)* m = &t.getCurrentModelViewMatrix(); // 
 currently
 }
 ----

 But IMO it would be a lot nicer if I could store the reference 
 like this:
 ----
 ref const(Matrix) m = t.getCurrentModelViewMatrix(); // nicer
 ----

 [Of course the name is exaggerated for the purpose of 
 demonstration.]

 May this be worth of an enhancement request?
Maybe, but I think you'd have to present a better argument. It's not obvious to me how `ref T x = y;` is supposed to be a lot nicer than `T* x = &y;`.
 Or was this  already rejected?
I don't know. But since it's a C++ thing, it's probably been discussed.
Mar 16 2015
next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 16 March 2015 at 19:20:09 UTC, anonymous wrote:
 On Monday, 16 March 2015 at 18:47:00 UTC, Namespace wrote:
    const(Matrix)* m = &t.getCurrentModelViewMatrix(); // 
 currently
 }
 ----

 But IMO it would be a lot nicer if I could store the reference 
 like this:
 ----
 ref const(Matrix) m = t.getCurrentModelViewMatrix(); // nicer
 ----

 [Of course the name is exaggerated for the purpose of 
 demonstration.]

 May this be worth of an enhancement request?
Maybe, but I think you'd have to present a better argument. It's not obvious to me how `ref T x = y;` is supposed to be a lot nicer than `T* x = &y;`.
 Or was this  already rejected?
I don't know. But since it's a C++ thing, it's probably been discussed.
The last time we discussed about scope, Walter suggested allowing `ref` for local variables. He might not be opposed to extend it further to members. On the other hand, `ref` has gained different semantics with DIP25 (something like scope, more or less), so this might collide with such a change. Anyway, the situation in D is not the same as in C++, because `ref` is not a type modifier, but a storage class.
Mar 16 2015
prev sibling parent "Namespace" <rswhite4 gmail.com> writes:
On Monday, 16 March 2015 at 19:20:09 UTC, anonymous wrote:
 On Monday, 16 March 2015 at 18:47:00 UTC, Namespace wrote:
    const(Matrix)* m = &t.getCurrentModelViewMatrix(); // 
 currently
 }
 ----

 But IMO it would be a lot nicer if I could store the reference 
 like this:
 ----
 ref const(Matrix) m = t.getCurrentModelViewMatrix(); // nicer
 ----

 [Of course the name is exaggerated for the purpose of 
 demonstration.]

 May this be worth of an enhancement request?
Maybe, but I think you'd have to present a better argument. It's not obvious to me how `ref T x = y;` is supposed to be a lot nicer than `T* x = &y;`.
It is, for example, not nullable. ;)
 Or was this  already rejected?
I don't know. But since it's a C++ thing, it's probably been discussed.
I will research this. Thank you.
Mar 16 2015
prev sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, March 16, 2015 18:46:59 Namespace via Digitalmars-d-learn wrote:
 May this be worth of an enhancement request? Or was this already
 rejected?
 And, no, I want no mutable references such as C++.
Walter has been adamantly against having ref variables like C++ has. They're a potential safety issue and add a fair bit of complication to the language. I doubt that suggesting that we have them as const-only would change his mind any - especially since that addresses none of the safety issues. - Jonathan M Davis
Mar 17 2015
parent reply "Namespace" <rswhite4 gmail.com> writes:
On Tuesday, 17 March 2015 at 09:56:09 UTC, Jonathan M Davis wrote:
 On Monday, March 16, 2015 18:46:59 Namespace via 
 Digitalmars-d-learn wrote:
 May this be worth of an enhancement request? Or was this 
 already
 rejected?
 And, no, I want no mutable references such as C++.
Walter has been adamantly against having ref variables like C++ has. They're a potential safety issue and add a fair bit of complication to the language. I doubt that suggesting that we have them as const-only would change his mind any - especially since that addresses none of the safety issues. - Jonathan M Davis
If I can't mutate them, where are the safety issues?
Mar 17 2015
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, March 17, 2015 09:59:59 Namespace via Digitalmars-d-learn wrote:
 On Tuesday, 17 March 2015 at 09:56:09 UTC, Jonathan M Davis wrote:
 On Monday, March 16, 2015 18:46:59 Namespace via
 Digitalmars-d-learn wrote:
 May this be worth of an enhancement request? Or was this
 already
 rejected?
 And, no, I want no mutable references such as C++.
Walter has been adamantly against having ref variables like C++ has. They're a potential safety issue and add a fair bit of complication to the language. I doubt that suggesting that we have them as const-only would change his mind any - especially since that addresses none of the safety issues. - Jonathan M Davis
If I can't mutate them, where are the safety issues?
With regards to what they refer to. For instance, ref const(Foo) getFoo(); ref const(Foo) foo = getFoo(); How long is the ref returned by getFoo even valid? Maybe it refers to memory that gets freed on the next line. The compiler can't know. So, foo may or may not stay valid, and so it's not safe unless the compiler can guarantee the lifetime of what foo refers to. Or, take this example which (unfortunately) currently compiles: ref int getBar(ref int bar) safe { return bar; } ref int getFoo() safe { int foo; return getBar(foo); } void main() { getFoo() = 7; } By the time getFoo returns, what it's returning is already invalid. So, the code _isn't_ safe, even though the compiler claims it is. Allowing something like void main() { ref const(int) foo = getFoo(); } would just perpetuate the problem. What foo refers to is _already_ invalid even without having to worry about whether it will stay valid when the code after it does whatever it does. I believe that the return attribute stuff that was recently added is intended to solve these issues, but I haven't really looked at it much yet, so I'm not very familiar with the details. And maybe those changes would make it so that allowing ref variables would work. I don't know. But const really isn't the issue. It's lifetime. It has to be guaranteed that what the ref refers to is valid for at least as long as the ref is. - Jonathan M Davis
Mar 17 2015
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/17/2015 11:14 AM, Jonathan M Davis via Digitalmars-d-learn wrote:

 Or, take this example which (unfortunately) currently compiles:

 ref int getBar(ref int bar)  safe
 {
      return bar;
 }

 ref int getFoo()  safe
 {
      int foo;
      return getBar(foo);
 }

 void main()
 {
      getFoo() = 7;
 }
[...]
 I believe that the return attribute stuff that was recently added is
 intended to solve these issues
Yes, it is available on git head (and works without safe): ref int getBar(return ref int bar) safe // <-- Add 'return' { return bar; } ref int getFoo() safe { int foo; return getBar(foo); // <-- Does not compile anymore }
 so I'm not very familiar with the details.
I think there are corner cases that even the 'return' attribute does not solve but I did not follow those discussions. Ali
Mar 17 2015
prev sibling parent "Kagamin" <spam here.lot> writes:
On Tuesday, 17 March 2015 at 18:14:48 UTC, Jonathan M Davis wrote:
 How long is the ref returned by getFoo even valid? Maybe it 
 refers to memory
 that gets freed on the next line. The compiler can't know.
The problem is not specific to variables, any reference type has that issue.
Mar 18 2015