Issue 3919: enumerate_view may invoke UB for sized common non-forward underlying ranges (original) (raw)
This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.
3919. enumerate_view may invoke UB for sized common non-forward underlying ranges
Section: 25.7.24 [range.enumerate] Status: WP Submitter: Patrick Palka Opened: 2023-04-07 Last modified: 2024-04-02
Priority: 3
View all issues with WP status.
Discussion:
For a sized common range, enumerate_view::end() is specified to callranges::distance. But ranges::distance is not necessarily well-defined for a sized non-forward range after calling ranges::begin (according to 25.4.4 [range.sized]).
So for a sized common non-forward underlying range, it seems callingenumerate_view::begin() followed by enumerate_view::end() may invoke UB and thus make enumerate_view potentially unusable for such ranges.
I suppose we might need to instead call and cache the result ofranges::distance from enumerate_view::begin() for such ranges.
[2022-04-12; Patrick Palka provides wording]
The proposed wording follows the suggestion provided by Tim Song, to simply make enumerate non-common for this case.
[2023-05-24; Reflector poll]
Set priority to 3 after reflector poll.
[Kona 2023-11-10; move to Ready]
[Tokyo 2024-03-23; Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4944.
- Modify 25.7.24.2 [range.enumerate.view], class template class
enumerate_viewsynopsis, as indicated:[…]
constexpr auto end() requires (!simple-view) {
if constexpr (forward_range && common_range && sized_range)
return iterator(ranges::end(base), ranges::distance(base));
else
return sentinel(ranges::end(base));
}
constexpr auto end() const requires range-with-movable-references {
if constexpr (forward_range && common_range && sized_range)
return iterator(ranges::end(base), ranges::distance(base));
else
return sentinel(ranges::end(base));
}
[…]