I guess this bug is related with the optimization of GCC 4.7.2.
The version built with VC 2010 or GCC 4.5.2 works fine.
The workaround is adding a volatile qualifier.
Additionally, I found some problems in Range#bsearch method.
-
The following example in documentation is wrong.
(0..4).bsearch {|i| 100 - i } #=> 1, 2 or 3
(0..4).bsearch {|i| 300 - i } #=> nil
(0..4).bsearch {|i| 50 - i } #=> nil
-
(0.0...Float::INFINITY).bsearch {|x| Math.log(x) >= 0 } returns nil instead of 1.0 on Windows.
-
(0.0..10).bsearch {|x| 7.0-x} returns nil instead of 7.0
Here is a patch for all above problems:
diff --git a/range.c b/range.c.new
index 7d30383..0e0fd14 100644
--- a/range.c
+++ b/range.c.new
@@ -513,9 +513,9 @@ range_step(int argc, VALUE *argv, VALUE range)
- satisfies the condition, it returns nil.
-
-
ary = [0, 100, 100, 100, 200]
-
switch (rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)) < 0) { \
-
switch (rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0))) { \
case 0: return val; \
-
case 1: smaller = 1; \
-
case -1: smaller = 0; \
-
volatile double nlow = -1.0, dec;
if (nlow > high) nlow = high;
count = BSEARCH_MAXCOUNT;
/* find lower bound by checking low, low*2, low*4, ... */
@@ -697,7 +698,6 @@ range_bsearch(VALUE range)
binsearch:
/* find the desired value within low..high /
/ where low is not -INFINITY and high is not INFINITY */
- org_high = high;
count = BSEARCH_MAXCOUNT;
while (low < high && count >= 0) {
mid = low + ((high - low) / 2);