[Bug libstdc++/61107] New: [4.8/4.9/4.10] stl_algo.h : std::__inplace_stable_partition() doesn't process the whole data range
tomytsai at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed May 7 22:46:00 GMT 2014
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61107
Bug ID: 61107
Summary: [4.8/4.9/4.10] stl_algo.h :
std::__inplace_stable_partition() doesn't process the
whole data range
Product: gcc
Version: 4.10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: tomytsai at gmail dot com
In GCC 4.8.2 / 4.9 (20140430 snapsot) / 4.10.0 (20140504 snapshot)
If we test the following code:
auto vec = vector<int> {1, 0, 1}
auto cmp = [] (int v) {return v == 0;};
std::__inplace_stable_partition( begin(vec), cmp, vec.size() )
final vec == {1, 0, 1}
(the expected result is {0, 1, 1})
It is because of the following line in stl_algo.h :
__inplace_stable_partition()
(from
http://gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/a01499_source.html#l01519)
1531 _ForwardIterator __right_split =
1532 std::__find_if_not_n(__middle, __right_len, __pred);
1533 if (__right_len)
1534 __right_split = std::__inplace_stable_partition(__middle,
1535 __pred,
1536 __right_len);
In line 1534, __middle should be replaced with __right_split. Otherwise,
the recursive call will start from __middle, with the updated __right_len
(modified by __find_if_not_n() ), That is, if __find_if_not_n() reduces
__right_len , some of the tailing data will leave unprocessed by
the current function.
Note this problem is not critical because:
1. The corresponding function __stable_partition_adaptive() has the right
logic (it uses __right_split instead of __middle ). Maybe someone forgot
to update __inplace_stable_partition() when he/she updated
__stable_partition_adaptive().
2. This function is only called when the available buffer size is 0. Otherwise,
__stable_partition_adaptive() will be called and it has mirrored all the
codes from __stable_partition_adaptive(), with the correct logic.
However it is still good to patch this bug. We can do either
1. Replace the __middle with __right_split , as shown above.
or 2. From stable_partition() , call __stable_partition_adaptive() exclusively.
This way we can totally remove __inplace_stable_partition(), as
__stable_partition_adaptive() is doing the same thing if the memory is
not enough (or totally not available).
Thanks!
Tomy
More information about the Gcc-bugs
mailing list