digitalmars.D.learn - Possible bug in RVO?
- Yuxuan Shui (9/9) Apr 03 2016 I have encountered a weird bug.
- Yuxuan Shui (40/50) Apr 03 2016 OK, I think I got a test case:
- Yuxuan Shui (30/40) Apr 03 2016 A slightly more reduced test case:
- Yuxuan Shui (3/22) Apr 03 2016 And LDC has the same problem with the first test case, but not
- Anonymouse (3/9) Apr 04 2016 No idea myself but that's where it seems to go wrong.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (15/24) Apr 04 2016 Looks like a bug. Just to make it more visible:
- Yuxuan Shui (3/24) Apr 04 2016 I filed an bug report here:
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?
Apr 03 2016
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.
Apr 03 2016
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); }
Apr 03 2016
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:And LDC has the same problem with the first test case, but not with the second one.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:
Apr 03 2016
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); // <-- boomreturn ret; }No idea myself but that's where it seems to go wrong.
Apr 04 2016
On 04/04/2016 09:36 AM, Anonymouse wrote:On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote: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? AliOn 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); // <-- boomreturn ret; }No idea myself but that's where it seems to go wrong.
Apr 04 2016
On Monday, 4 April 2016 at 21:31:08 UTC, Ali Çehreli wrote:On 04/04/2016 09:36 AM, Anonymouse wrote:I filed an bug report here: https://issues.dlang.org/show_bug.cgi?id=15869On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote: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[...]assert(x.aa.length > 0); // <-- boom[...]No idea myself but that's where it seems to go wrong.
Apr 04 2016