Re: Possible bug in RVO?

2016-04-04 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 21:31:08 UTC, Ali Çehreli wrote:

On 04/04/2016 09:36 AM, Anonymouse wrote:

On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote:

[...]

assert(x.aa.length > 0);  // <-- boom

[...]


No idea myself but that's where it seems to go wrong.


Looks like a bug. Just to make it more visible:

auto clobber(ref Set x, ref Set o) {
writefln("entered clobber- x.aa: %s", x.aa);
Set ret;
writefln("did not touch x.aa - x.aa: %s", x.aa);
ret.aa = x.aa;
return ret;
}

x.aa changes during the second call:

entered clobber- x.aa: [1:true]
did not touch x.aa - x.aa: [1:true]
entered clobber- x.aa: [1:true]
did not touch x.aa - x.aa: []  <-- What happened?

Ali


I filed an bug report here: 
https://issues.dlang.org/show_bug.cgi?id=15869


Re: Possible bug in RVO?

2016-04-04 Thread Ali Çehreli via Digitalmars-d-learn

On 04/04/2016 09:36 AM, Anonymouse wrote:

On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote:

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:
auto clobber(ref Set x, ref Set o) {
Set ret;
ret.aa = x.aa;

assert(x.aa.length > 0);  // <-- boom

return ret;
}


No idea myself but that's where it seems to go wrong.


Looks like a bug. Just to make it more visible:

auto clobber(ref Set x, ref Set o) {
writefln("entered clobber- x.aa: %s", x.aa);
Set ret;
writefln("did not touch x.aa - x.aa: %s", x.aa);
ret.aa = x.aa;
return ret;
}

x.aa changes during the second call:

entered clobber- x.aa: [1:true]
did not touch x.aa - x.aa: [1:true]
entered clobber- x.aa: [1:true]
did not touch x.aa - x.aa: []  <-- What happened?

Ali



Re: Possible bug in RVO?

2016-04-04 Thread Anonymouse via Digitalmars-d-learn

On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote:

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:
auto clobber(ref Set x, ref Set o) {
Set ret;
ret.aa = x.aa;

  assert(x.aa.length > 0);  // <-- boom

return ret;
}


No idea myself but that's where it seems to go wrong.


Re: Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow 
this:


auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?


A slightly more reduced test case:

struct Set {
void insert(ulong v) {
aa[v] = true;
}
@disable this(this);
bool[ulong] aa;
}
auto clobber(ref Set x, ref Set o) {
Set ret;
ret.aa = x.aa;
return ret;
}
struct XX {
Set a, b, tmp;
this(int n) {
a.insert(1);
		//a.aa[1] = true;  <--- Swap above line with this doesn't 
trigger the bug

tmp = a.clobber(b);
a = a.clobber(b);
}
}
void main(){
import std.stdio;
XX xx = XX(0);
writeln(xx.a.aa.length);
writeln(xx.tmp.aa.length);
}


Re: Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote:

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow 
this:


auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?


A slightly more reduced test case:



And LDC has the same problem with the first test case, but not 
with the second one.





Re: Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow 
this:


auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?


OK, I think I got a test case:

import std.traits;
struct Set {
public:
void insert(ulong v) {
aa[v] = true;
}
size_t size() const {
return aa.length;
}
auto opBinary(string op)(ref Set o) const {
Set ret;
foreach(k; aa.byKey)
if (k !in o.aa)
ret.insert(k);
return ret;
}
@disable this(this);
bool[ulong] aa;
}

struct XX {
Set a, b, tmp;
this(int n) {
a.insert(n);
tmp = a-b;
a = a-b;
}
}
void main(){
import std.stdio;
XX xx = XX(1000);
writeln(xx.a.size);
writeln(xx.tmp.size);
}

This does not happen when 'a' is on stack, that's why I was 
having trouble reproducing it.


I don't think this is valid code, because Set has disabled 
post-blit, 'a = a-b' should report an error. However, I don't 
think current behavior of dmd is correct either.


Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow this:

auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?