Title
`ranges::distance` does not work with volatile iterators
Status
new
Section
[range.iter.op.distance]
Submitter
Hewill Kang

Created on 2025-04-12.00:00:00 last changed 1 month ago

Messages

Date: 2025-04-13.09:29:22

Proposed resolution:

This wording is relative to N5008.

  1. Modify [range.iter.op.distance] as indicated:

    template<class I, sized_sentinel_for<decay_t<I>> S>
      constexpr iter_difference_t<decay_t<I>> ranges::distance(I&& first, S last);
    

    -3- Effects: Equivalent to:

    if constexpr (!is_array_v<remove_reference_t<I>>)
      return last - first;
    else
      return last - static_cast<const decay_t<I>&>(first);
    
Date: 2025-04-12.00:00:00

After LWG 3664, `ranges::distance` computes the distance between `last` and `first` by returning last - static_cast<const decay_t<I>&>(first) when the two are subtractable. However, this will cause a hard error if first is volatile-qualified (demo):

#include <iterator>

int main() {
  int arr[] = {1, 2, 3};
  int* volatile ptr = arr;
  // return std::distance(ptr, arr + 3);      // this is ok
  return std::ranges::distance(ptr, arr + 3); // hard error
}

The resolution changes the Effects of LWG 3664 from "cute" to "noncute".

History
Date User Action Args
2025-04-13 09:29:22adminsetmessages: + msg14721
2025-04-12 00:00:00admincreate