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]
(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..4).bsearch {|i| 100 - ary[i] } #=> 1, 2 or 3
(0..4).bsearch {|i| 300 - ary[i] } #=> nil
(0..4).bsearch {|i| 50 - ary[i] } #=> nil
You must not mix the two modes at a time; the block must always
return either true/false, or always return a number. It is
@@ -543,10 +543,10 @@ range_bsearch(VALUE range)
smaller = 0;
}
else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
@@ -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 */
This issue was solved with changeset r37662.
Luis, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
range.c (range_bsearch): fix some bugs: a documentation bug, a wrong
condition, missed break in switch/case, and workaround for GCC
optimization. See [ruby-core:49364] in detail. A great patch from
Heesob Park. [Bug #7352] [Feature #4766]
array.c (rb_ary_bsearch): fix similar bug (missed break).
test/ruby/test_range.rb: add two test cases for above.
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.
I've committed your patch, my MEGA thanks!
I would really like you to have a commit bit. Are you willing?
Matz, what do you thing? He is a great all-round player; his
contribution to Ruby includes deadlock issues (his patches was
applied by kosaki), windows issues (accepted by usa and naruse),
algorithmic issue (accepted by mrkn and me), documentation
issues (by nobu), etc.