以下是否根据C ++标准定义明确?
char* p = 0;
std::equal(p, p, p);
问题是这样的:
标准是否要求以std::equal(begin1, end1, begin2)
的方式实施begin1 == end1
,begin1
和begin2
可以是任何指针,即使是指向的指针也是如此到一个有效的记忆对象?
我认为这是标准的目的,但我未能找到一个明确的陈述。
我担心这一点的原因是VisualStudio显然试图检查begin2
的“有效性”,即使begin1 == end1
也是如此。这与我对标准要求的理解相矛盾。
编辑:以下是我认为违反标准的VS 2012的代码:
template<class _InIt1, class _InIt2> inline
bool equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2)
{ // compare [_First1, _Last1) to [First2, ...)
_DEBUG_RANGE(_First1, _Last1);
_DEBUG_POINTER(_First2);
return (_Equal1(_Unchecked(_First1), _Unchecked(_Last1), _First2, _Is_checked(_First2)));
}
template<class _Ty> inline
void _Debug_pointer(const _Ty *_First, _Dbfile_t _File, _Dbline_t _Line)
{ // test iterator for non-singularity, const pointers
if (_First == 0)
_DEBUG_ERROR2("invalid null pointer", _File, _Line);
}
答案 0 :(得分:9)
所以我们有25.2.1 / 1说:
返回:如果对于[first1,last1]范围内的每个迭代器i,则返回true 遵循相应的条件:* i == *(first2 +(i - first1)),pred(* i,*(first2 +(i - first1)))!= false。
否则, 返回false。
在你的情况下,[0,0]范围内没有迭代器,因此范围内的“每个”迭代器都通过了测试,但是不应该进行实际测试(因为在测试的范围内不存在迭代器)
对我来说,这看起来像是一个VisualStudio的错误。
答案 1 :(得分:2)
正如@Zac指出的那样,这个检查是Visual Studio在安全性方面的额外迂腐。如果您希望Visual Studio在调试版本中更接近标准,则可以通过设置宏_ITERATOR_DEBUG_LEVEL to 0来关闭此行为。
答案 2 :(得分:0)
通过您的更新,很明显它不违反标准,而是调试检查。如果在Release模式下编译它,则不会运行这些检查,并且该函数与标准的描述匹配。
在调试模式下获取该信息非常有用,因为它可以帮助您找到一些难以发现的错误。
答案 3 :(得分:0)
C ++ 11标准在24.2.1 / 5中声明“[i,i)是一个空范围”。
然而,在24.2.1 / 5中,它首先暗示0必须是奇异值,然后指出“大多数表达式的结果对于奇异值是未定义的”。然后列出未定义行为的例外,但不包括比较。
所以也许未定义比较奇异迭代器的相等性,因此无法评估[i,i]。
这也表明您的运行时错误发生在名为_Equal1()的函数中。
我认为标准对此很模糊,我不确定它是Visual Studio 2012中的一个错误。
<12>。有效和奇异迭代器的含义未明确的http://cplusplus.github.io/LWG/lwg-unresolved.html对于这种混乱也很有趣......