3989. The whole range for an iterator obtained from a std::span or std::basic_string_view is not clear

Section: 27.3 [string.view], 23.7.2.2 [views.span] Status: New Submitter: Jiang An Opened: 2023-08-29 Last modified: 2023-10-30

Priority: 3

View other active issues in [string.view].

View all other issues in [string.view].

View all issues with New status.

Discussion:

It is unclear whether the following program has undefined behavior:

#include <cassert>
#include <span>
#include <string_view>

int main()
{
  int arr[2]{42, 84};
  std::span<int> sp1{arr, 1};
  std::span<int> sp2{arr + 1, 1};

  assert(sp2.begin() - sp1.begin() == 1); // Is this well-defined?
  assert(sp2.begin() == sp1.end());       // ditto
  assert(*sp1.end() == 84);               // ditto

  const char str[]{"string"};
  std::string_view sv1{str, 3};
  std::string_view sv2{str + 3, 3};

  assert(sv2.begin() - sv1.begin() == 3); // Is this well-defined?
  assert(sv2.begin() == sv1.end());       // ditto
  assert(*sv1.end() == 'i');              // ditto
}

Currently MSVC STL strictly diagnose the arithmetic between different spans/basic_string_views, even the views are on the same underlying range (see this Github issue). libstdc++ and libc++ silently accept these operations.

Perhaps the standard should clarify what the whole ranges are when determining whether operations between iterators from different views on the same underlying range is well-defined.

[2023-10-30; Reflector poll]

Set priority to 3 after reflector poll. Libc++ diagnoses the example with the right macros defined. "Should substr and remove_suffix tighten the bounds or copy them from the original view?"

Proposed resolution: