digitalmars.D.learn - this is not an lvalue
- Andrey (10/10) Dec 13 2016 Hello, I'm newbie in D. I'm trying to rewrite my project from C++
- Adam D. Ruppe (3/4) Dec 13 2016 You probably don't want the `ref` there, nor likely on any other
- kink (5/9) Dec 13 2016 Assuming `Parameter` is a class and not a struct, yes. Be sure to
- Adam D. Ruppe (4/5) Dec 13 2016 Even if it is a struct, ref wouldn't make a difference here
- kinke (3/8) Dec 13 2016 I should have been more precise, I meant the type of `this`, not
- Andrey (3/8) Dec 15 2016 Thanks it works, but where should I use the ref? for example in
- Adam D. Ruppe (78/79) Dec 15 2016 Only when you need it, break the habit of using it everywhere.
- kinke (14/17) Dec 15 2016 But D doesn't make this easy, as it disallows rvalues to be
- Andrey (2/7) Dec 15 2016
- Adam D. Ruppe (7/9) Dec 15 2016 Yes, though remember that `in` does have a specific meaning (even
Hello, I'm newbie in D. I'm trying to rewrite my project from C++ and now I get strange warning: src/e2ml/node.d(23,22): Deprecation: this is not an lvalue As I write the following code void moveTo(ref Parameter parent) { this.p_parent.removeValue(this); this.p_parent = parent; this.updatePath(); } How to fix it?
Dec 13 2016
On Tuesday, 13 December 2016 at 15:09:10 UTC, Andrey wrote:void moveTo(ref Parameter parent) {You probably don't want the `ref` there, nor likely on any other method definitions (especially check removeValue).
Dec 13 2016
On Tuesday, 13 December 2016 at 16:23:16 UTC, Adam D. Ruppe wrote:On Tuesday, 13 December 2016 at 15:09:10 UTC, Andrey wrote:Assuming `Parameter` is a class and not a struct, yes. Be sure to check out the crucial distinction between the two in D (reference won't get far.void moveTo(ref Parameter parent) {You probably don't want the `ref` there, nor likely on any other method definitions (especially check removeValue).
Dec 13 2016
On Tuesday, 13 December 2016 at 17:26:28 UTC, kink wrote:Assuming `Parameter` is a class and not a struct, yes.Even if it is a struct, ref wouldn't make a difference here because the variable is assigned to a member, which means ref would get lost.
Dec 13 2016
On Tuesday, 13 December 2016 at 17:52:21 UTC, Adam D. Ruppe wrote:On Tuesday, 13 December 2016 at 17:26:28 UTC, kink wrote:I should have been more precise, I meant the type of `this`, not `Parameter` (I actually assumed both would be the same). ;)Assuming `Parameter` is a class and not a struct, yes.Even if it is a struct, ref wouldn't make a difference here because the variable is assigned to a member, which means ref would get lost.
Dec 13 2016
On Tuesday, 13 December 2016 at 16:23:16 UTC, Adam D. Ruppe wrote:On Tuesday, 13 December 2016 at 15:09:10 UTC, Andrey wrote:Thanks it works, but where should I use the ref? for example in C++ I always used pointers for structs, classes in stack etc.:void moveTo(ref Parameter parent) {You probably don't want the `ref` there, nor likely on any other method definitions (especially check removeValue).void open(const std::string &fileName) {...}
Dec 15 2016
On Thursday, 15 December 2016 at 13:59:05 UTC, Andrey wrote:Thanks it works, but where should I use the ref?Only when you need it, break the habit of using it everywhere. If it is a value type and you want modifications to the variable itself be seen outside the function, use it: void foo(ref int something) { something++; } void main() { int a = 1; foo(a); assert(a == 2); } Since int is value and you want to see the change to the local outside the function, ref is used. However, notice: void foo(int[] arr) { arr[0] = 5; } void main() { int[2] a = [1, 2]; foo(a[]); assert(a[0] == 5); } No need for ref there, because the slice is already a reference to its contents. However, if I wanted to *append* to the slice and see that length change outside, ref may be appropriate. This brings me to classes: interfaces and class objects in D are already automatically pointers internally, just like slices. void foo(Object o) { /* already like Object* in C++ */ o.modify(); } void main() { Object o = new Object(); foo(o); // o has been modified } No need for ref to see changes to the object's internals outside. However, if you want to rebind the object: void foo(ref Object o) { /* now like Object** in C++ */ o = new Object(); } void main() { Object o; foo(o); // o represents the new Object } ref is needed there - this is changing the variable itself, not what is inside it. With structs, it depends on what you are doing with it - are you changing the variable itself or something inside it? And what is inside. struct Foo { int a; } That Foo acts just like int, so use or don't use ref as if it was an int. struct Foo { int[] a; } That one is just like a slice, no need to `ref` that unless you want to change the outer portion. The contents are implicitly referenced and not copied. struct Foo { int[4] a; } Well, this is a value type again, but bigger. Still, I'd say follow the same rule as plain `int` - only ref that if you need modifications to be seen outside the function. struct Foo { ubyte[1024 * 1024] oneMegabyte; } OK, you might want to ref that one just because the copy to the function may be expensive and the compiler is not necessarily going to optimize that (BUT the compiler MIGHT optimize it! If the function gets inlined and it isn't modified, it may compile to the same thing anyway. Still, I'd probably ref that myself, or wrap it up in pointers or maybe even a class for its interface.) General rule of thumb: if you are refing for performance, actually check it before and after first, ref isn't always faster.
Dec 15 2016
On Thursday, 15 December 2016 at 15:29:13 UTC, Adam D. Ruppe wrote:General rule of thumb: if you are refing for performance, actually check it before and after first, ref isn't always faster.But D doesn't make this easy, as it disallows rvalues to be passed by ref. It's a very common pitfall for C++ guys. `auto ref` for templates is an insufficient workaround/hack for that. On a side note, wrt. `ref isn't always faster` (due to the indirection): it's almost always faster on Windows 64, as all value types > 64 bit (excluding vectors for the vectorcall convention, but let's keep things simple) need to be passed by reference (ABI requirement). What this means and what keeps on being ignored is that passing a D value type > 64 bits by value (to allow rvalue args, although the parameter is a read-only one) yields the worst of both worlds - a bitcopy of the original argument passed by reference.
Dec 15 2016
On Tuesday, 13 December 2016 at 16:23:16 UTC, Adam D. Ruppe wrote:On Tuesday, 13 December 2016 at 15:09:10 UTC, Andrey wrote:In D, probably, I could write something like this:void moveTo(ref Parameter parent) {You probably don't want the `ref` there, nor likely on any other method definitions (especially check removeValue).void open(in string fileName) {...}
Dec 15 2016
On Thursday, 15 December 2016 at 14:05:08 UTC, Andrey wrote:In D, probably, I could write something like this:Yes, though remember that `in` does have a specific meaning (even though the compiler rarely enforces it): it means you promise not to modify it nor keep a reference to it. So don't use `in` on anything you want to keep as a member or global variable, it is something you will just look at inside this function then let go.void open(in string fileName) {...}
Dec 15 2016