Deque随机访问迭代器比较会产生意外结果

Ser*_* K. 2 c++ gcc iterator deque visual-c++

我有这个小片段在GCC上表现得非常好(如预期的那样).

#include <deque>
#include <iostream>
#include <algorithm>

std::deque<int> values = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int main()
{
    typedef std::deque<int>::iterator buf_iterator;

    buf_iterator itr = values.begin() + 1;

    const int K = 5;

    buf_iterator i = std::max(itr - K, values.begin());

    int pos = i - values.begin();

    std::cout << *i << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,在MSVC 2013和2015上运行会产生调试断言:"deque迭代器不可解除引用".的值pos在这种情况下-4,而零的预期.

  1. 谁是对的,GCC还是Visual Studio?
  2. 为什么?

Jon*_*ely 10

itr - K 是未定义的行为,因为它在开头之前递减指针,即它等效于:

auto it = values.begin();
--it;
Run Code Online (Sandbox Code Playgroud)

这是未定义的.

GCC将通过_GLIBCXX_DEBUG定义:

/home/jwakely/gcc/5/include/c++/5.0.0/debug/safe_iterator.h:428:error: 
    attempt to retreat a dereferenceable iterator 5 steps, which falls 
    outside its valid range.

Objects involved in the operation:
iterator @ 0x0x7fff6fdb3450 {
type = N11__gnu_debug14_Safe_iteratorINSt9__cxx199815_Deque_iteratorIiRiPiEENSt7__debug5dequeIiSaIiEEEEE (mutable iterator);
  state = dereferenceable;
  references sequence with type `NSt7__debug5dequeIiSaIiEEE' @ 0x0x606360
}
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

  • 正确,显然;-)`itr - std :: min(k,std :: distance(values.begin(),itr))` (2认同)

T.C*_*.C. 5

谁是对的,GCC还是Visual Studio?

都.

为什么?

递减begin()是未定义的行为.