More n3644 changes - forward_list and deque

Howard Hinnant hhinnant at apple.com
Tue Aug 6 08:40:23 PDT 2013


On Aug 6, 2013, at 10:23 AM, Marshall Clow <mclow.lists at gmail.com> wrote:

> This one is quite straightforward.
> 
> Comparing a value_initialized iterator to a non-value initialized iterator is supposed to be undefined behavior.
> I'd really like it if libc++'s debug mode could catch that, but I don't really see how (at least for vector/array/deque/forward_list).


Debug mode will catch comparisons using < > <= >=, but not == and != (for vector/array/deque):

#include <vector>
#include <cassert>

int
main()
{
    std::vector<int> v;
    std::vector<int>::iterator i1{};
    std::vector<int>::iterator i2{};
    auto j1 = v.begin();
    auto j2 = v.end();
    assert(j1 == j2);    // ok
    assert(i1 == i2);    // ok
    assert(i1 == j1);    // ok
    assert(!(j1 < j2));  // ok
    bool b1 = i1 < i2;   // aborts in debug mode, false in release mode
    bool b2 = i1 < j1;   // aborts in debug mode, false in release mode
}

vector::iterator is allowed to be a pointer.
This behavior mimics the defined/undefined behavior for pointers described in [expr.eq] and [expr.rel].  j1 and j2 point to the same object, so they are both equality comparable and less-than comparable.  i1, i2 both point to different objects (none at all), and not to the same object as j1 and j2.  [expr.eq] says that all pointers are equality comparable, and this is reflected in the above test.  However [expr.rel] defines operator<() only for pointers pointing into the same object.  Debug mode catches this.  Release mode doesn't (it would be too expensive to catch in release mode).

I believe this is exactly the behavior we want.

Looks good to me.  Please commit.  Thanks!

Howard




More information about the cfe-commits mailing list