双端队列随机访问迭代器比较产生意外结果
Deque random access iterator comparison produces unexpected results
我有这个小片段,它在 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;
}
但是,MSVC 2013 和 2015 上的 运行 会生成调试断言:"deque iterator is not dereferencable"。在这种情况下,pos
的值为 -4
,而预期为零。
- 谁是对的,GCC 还是 Visual Studio?
- 为什么?
Who is right, GCC or Visual Studio?
两者都有。
Why?
递减 begin()
是未定义的行为。
itr - K
是未定义的行为,因为它在开始之前递减指针,即它等同于:
auto it = values.begin();
--it;
那是未定义的。
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)
我有这个小片段,它在 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;
}
但是,MSVC 2013 和 2015 上的 运行 会生成调试断言:"deque iterator is not dereferencable"。在这种情况下,pos
的值为 -4
,而预期为零。
- 谁是对的,GCC 还是 Visual Studio?
- 为什么?
Who is right, GCC or Visual Studio?
两者都有。
Why?
递减 begin()
是未定义的行为。
itr - K
是未定义的行为,因为它在开始之前递减指针,即它等同于:
auto it = values.begin();
--it;
那是未定义的。
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)