2

In n3644 - Null Forward Iterators, it says:

The result of comparing a value-initialized iterator to an iterator with a non-singular value is undefined.

vector<int> v = {1,2,3};
auto ni = vector<int>::iterator();
auto nd = vector<double>::iterator();
ni == ni; // True.
nd != nd; // False.
v.begin() == ni; // Undefined behavior (likely false in practice).
v.end() == ni; // Undefined behavior (likely false in practice).
ni == nd; // Won’t compile.
  • What does non-singular value mean?
  • Why is this undefined behavior?
  • Hm... I think that default-initialized iterator points to undefined place, like default-initialized raw pointer, and it shouldn't be used at all until set. – GingerPlusPlus Oct 05 '14 at 19:12
  • The semantics for comparing iterators into different containers are not defined for efficiency, and can any container be equal to no container? No, so the definition is unsurprising, and might be neccessary for efficiency. – Deduplicator Oct 05 '14 at 19:17

1 Answers1

1

You ask two very different questions. Your question about singular vs. non-singular is already answered here, so I will be ignoring that question, and only focusing on the question that isn't a duplicate.

Some containers may use special iterator values that look exactly like a default-constructed iterator value. For instance, iterators that do not have a valid pointer value for the iterator returned by end() may use their iterator type's equivalent of a null pointer to represent those.

Requiring the comparison to evaluate to true for those cases means that the implementation is forced to never change, even if a better approach for those iterator values is devised in the future.

Requiring the comparison to evaluate to false for those cases means that the implementation is forced to change.

Making the comparison undefined gives implementations the freedom they may need.

Xarn points out in the comments that it might have been a better choice to make the comparison give an unspecified result (either false or true, but no other options). That would have been a valid option, but the behaviour at the time of the proposal was already to disallow comparisons to iterators that do not come from the same containers (undefined behaviour, not unspecified results), and as far as I can tell, this proposal merely sought not to change anything that wasn't necessary, so left it as it was.

One valid argument for making it undefined rather than unspecified is that some implementations may want to provide special debugging iterators where invalid comparisons, that almost certainly are a programmer error, abort the program with a useful message.

Community
  • 1
  • 1
  • 1
    I so hope for the next standard, when they want to have ranges integrated, as well as end-iterator-types. Will be faster because there won't be a need for goofy end-iterators with magic values any more. – Deduplicator Oct 05 '14 at 19:25
  • Requiring the comparison to be true makes absolutely no sense logically for lots of reasons, I won't list them all. Making the comparison false on the other hand would be a perfectly reasonable choice. Since a non-singular value doesn't point to anything, it's reasonable to say it's not equal to anything, similar to NaN for floating point. And it's also perfectly reasonable to implement. I'd need to see a concrete example of a container for which forcing this comparison to be false in order to be convinced of what you're saying. I think the standard didn't define, because it just didnt. – Nir Friedman Oct 05 '14 at 19:32
  • @Nir Like I said, current implementations may be using such iterator values. The fact that it's possible to implement them differently doesn't change that there is a cost (time and breakage of compatibility) to it. –  Oct 05 '14 at 19:45
  • Wouldn't unspecified be much better than undefined in this case? There still wouldn't be anything forcing nonperformant implementation, but you wouldn't be toying around with your code potentially exploding. – Xarn Oct 05 '14 at 19:58
  • @Xarn Good question, and I've now addressed it in my answer. –  Oct 05 '14 at 20:37