You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
<span>: checked iterators became too intolerant #1435
Describe the bug
Checked iterators controlled by _ITERATOR_DEBUG_LEVEL provide some safe guarantee, but these assertions became more and more intolerant for programming in normal styles.
Expected behavior
Both these two span s1 and s2 came from a, hence they share the same underlying sequence.
I think this design makes iterators of the same type pointing to the same element not equivalent. (may be an LWG issue?)
From a programmer’s point of view, the code snippet above is a common requirement, especially when parsing certain data.
STL version
Microsoft Visual Studio Community 2019
Version 16.7.7
I think this should be submitted as an LWG issue. We believed we were strictly enforcing the Standard's intent, but the Standardese doesn't appear to be crystal clear to me.
WG21-N4868 22.7.3.7 [span.iterators]/2 says "All requirements on container iterators (22.2) apply to span::iterator as well." but it is not completely clear what "different spans" are, unlike different vectors. Certainly, spans that have the same data and size (i.e. are copies) are compatible for the purposes of iterator comparison/subtraction, etc., but what about overlapping spans or even disjoint spans? (e.g. getting a span to the first half and second half of a range).
My preference would be for the Standard to say what we are currently enforcing (only same data and size are compatible), so if you want to subtract addresses, you need to do so with raw pointers. The span philosophy is to discourage unsafe code, and subtracting iterators to potentially different ranges is potentially unsafe. However, if the Standard clearly said that overlapping spans have compatible iterators, or even that span iterator operations are valid when the underlying pointer operations are valid, we would change our checks accordingly.
The problem is that we cannot compare arbitrary pointers. Say we habe an array a and an array b, then comparing any pointer from a with any pointer from b is forbidden.
So while the example alludes that it "could" work, the general case is impossible.
Then there is also a problem with constexpr support. Yes this works for array, but not for vector (at least currently) and other user provided containers.
So long story short. This is not something we could vor should support IMHO. If the user really wants to he can always fall back to pointers via to_address
Just want to mention that gsl::span has the same "problem" at least in the past. There you couldn't even compare two iterators from two spans referring exactly the same range (e.g. if they belonged to two copies of the same iterator).
Back then that was a deliberate decision by the inventor, so I wouldn't at all be surprised, if that is also a by design limitation of std::span, even if I don't agree with it.
Activity
StephanTLavavej commentedon Nov 8, 2020
I think this should be submitted as an LWG issue. We believed we were strictly enforcing the Standard's intent, but the Standardese doesn't appear to be crystal clear to me.
WG21-N4868 22.7.3.7 [span.iterators]/2 says "All requirements on container iterators (22.2) apply to
span::iteratoras well." but it is not completely clear what "different spans" are, unlike different vectors. Certainly, spans that have the samedataandsize(i.e. are copies) are compatible for the purposes of iterator comparison/subtraction, etc., but what about overlapping spans or even disjoint spans? (e.g. getting a span to the first half and second half of a range).My preference would be for the Standard to say what we are currently enforcing (only same
dataandsizeare compatible), so if you want to subtract addresses, you need to do so with raw pointers. Thespanphilosophy is to discourage unsafe code, and subtracting iterators to potentially different ranges is potentially unsafe. However, if the Standard clearly said that overlapping spans have compatible iterators, or even that span iterator operations are valid when the underlying pointer operations are valid, we would change our checks accordingly.miscco commentedon Nov 8, 2020
This is not possible as far as I know.
The problem is that we cannot compare arbitrary pointers. Say we habe an array a and an array b, then comparing any pointer from a with any pointer from b is forbidden.
So while the example alludes that it "could" work, the general case is impossible.
Then there is also a problem with
constexprsupport. Yes this works for array, but not for vector (at least currently) and other user provided containers.So long story short. This is not something we could vor should support IMHO. If the user really wants to he can always fall back to pointers via to_address
MikeGitb commentedon Nov 8, 2020
Just want to mention that gsl::span has the same "problem" at least in the past. There you couldn't even compare two iterators from two spans referring exactly the same range (e.g. if they belonged to two copies of the same iterator).
Back then that was a deliberate decision by the inventor, so I wouldn't at all be surprised, if that is also a by design limitation of std::span, even if I don't agree with it.
frederick-vs-ja commentedon Oct 3, 2023
LWG-3989 has been filed for this.