digitalmars.D.bugs - [Issue 8886] New: [CTFE] a check failure of memory block inclusion
- d-bugmail puremagic.com (50/50) Oct 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8886
- d-bugmail puremagic.com (31/31) Oct 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8886
- d-bugmail puremagic.com (17/17) Oct 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8886
http://d.puremagic.com/issues/show_bug.cgi?id=8886 Summary: [CTFE] a check failure of memory block inclusion Product: D Version: D2 Platform: All OS/Version: All Status: NEW Keywords: CTFE Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: k.hara.pg gmail.com From the comment at https://github.com/D-Programming-Language/druntime/pull/335 --- version = bug; bool foo(const(int)[] a, const(int)[] b) { version(bug) { return a.length && b.ptr >= a.ptr && b.ptr + b.length <= a.ptr + a.length; } else { if (a.length && b.length) { auto bend = b.ptr + b.length; auto aend = a.ptr + a.length; return a.ptr <= b.ptr && bend <= aend; } return false; } } bool bug1() { auto a1 = [1,2,3,4,5]; return foo(a1[0..4], a1[2..4]); } bool bug2() { auto a1 = [1,2,3,4,5]; auto a2 = [1,2,3,4,5]; return foo(a1[0..4], a2[2..4]); } static assert( bug1()); static assert(!bug2()); // Fails CTFE when version = bug; defines. --- -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8886 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic CC| |clugdbug yahoo.com.au This behaviour is intentional. The relevant line is: return a.length && b.ptr >= a.ptr && b.ptr + b.length <= a.ptr + a.length; This means: return (a.length && b.ptr >= a.ptr) && b.ptr + b.length <= a.ptr + a.length; If the b.ptr < a.ptr, then the first subexpression fails, and because of short-circuit evaluation, b.ptr + b.length <= a.ptr + a.length is never evaluated. What you actually want is: return a.length && (b.ptr >= a.ptr && b.ptr + b.length <= a.ptr + a.length); Now in this particular case, the compiler could recognize e1 && e2 && e3 but it won't work in general, I think it makes things unpredictable. Changing to a diagnostic bug. I'm so disappointed, I went to a lot of trouble to give a good error message (even using the variable names you used!), and it seems it's still not clear enough. Any suggestions? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8886 To clarify: When I say "it won't work in general", the problem is things like: a < b && c < d && e > f If a and b are pointers to the same memory block, then a < b is OK, and this expression means: a < b && isInside(c..e, d..f) but if a and b are different pointers, then it would be: isInside(a..c, b..d) && e > f which is OK as long as e and f are in the same memory block. then there is an explosion of possible cases, and many similar things _still_ aren't handled ( eg, a1 < b1 && c1 < d1 && a2 > b2 && c2 > d2, why isn't this recognized as two isInside operations?) So the rule is simple: they have to be part of a single && or || expression. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 24 2012