是`char * p = 0; std :: equal(p,p,p)`根据C ++标准定义良好?

时间:2013-10-01 15:57:25

标签: c++ visual-studio stl

以下是否根据C ++标准定义明确?

char* p = 0;
std::equal(p, p, p);

问题是这样的:

标准是否要求以std::equal(begin1, end1, begin2)的方式实施begin1 == end1begin1begin2可以是任何指针,即使是指向的指针也是如此到一个有效的记忆对象?

我认为这是标准的目的,但我未能找到一个明确的陈述。

我担心这一点的原因是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);
}

4 个答案:

答案 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对于这种混乱也很有趣......

相关问题