Re: this is not an lvalue

2016-12-15 Thread kinke via Digitalmars-d-learn
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.


Re: this is not an lvalue

2016-12-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 15 December 2016 at 14:05:08 UTC, Andrey wrote:

In D, probably, I could write something like this:

void open(in string fileName) {...}


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.


Re: this is not an lvalue

2016-12-15 Thread Adam D. Ruppe via Digitalmars-d-learn

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.


Re: this is not an lvalue

2016-12-15 Thread Andrey via Digitalmars-d-learn

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:

void moveTo(ref Parameter parent) {


You probably don't want the `ref` there, nor likely on any 
other method definitions (especially check removeValue).


In D, probably, I could write something like this:

void open(in string fileName) {...}


Re: this is not an lvalue

2016-12-15 Thread Andrey via Digitalmars-d-learn

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:

void moveTo(ref Parameter parent) {


You probably don't want the `ref` there, nor likely on any 
other method definitions (especially check removeValue).


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 open(const std::string &fileName) {...}


Re: this is not an lvalue

2016-12-13 Thread kinke via Digitalmars-d-learn

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:

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.


I should have been more precise, I meant the type of `this`, not 
`Parameter` (I actually assumed both would be the same). ;)


Re: this is not an lvalue

2016-12-13 Thread Adam D. Ruppe via Digitalmars-d-learn

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.


Re: this is not an lvalue

2016-12-13 Thread kink via Digitalmars-d-learn

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:

void moveTo(ref Parameter parent) {


You probably don't want the `ref` there, nor likely on any 
other method definitions (especially check removeValue).


Assuming `Parameter` is a class and not a struct, yes. Be sure to 
check out the crucial distinction between the two in D (reference 
vs. value types, similar to C# class and struct), otherwise you 
won't get far.


Re: this is not an lvalue

2016-12-13 Thread Adam D. Ruppe via Digitalmars-d-learn

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).


this is not an lvalue

2016-12-13 Thread Andrey via Digitalmars-d-learn
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?