Re: Possible bug in RVO?
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?
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?
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?
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?
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?
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?
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?