Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是'char*p=0;std::equal(p,p,p)`根据C+定义良好+;标准 是按照C++标准定义的吗?< /P> char* p = 0; std::equal(p, p, p);_C++_Visual Studio_Stl - Fatal编程技术网

是'char*p=0;std::equal(p,p,p)`根据C+定义良好+;标准 是按照C++标准定义的吗?< /P> char* p = 0; std::equal(p, p, p);

是'char*p=0;std::equal(p,p,p)`根据C+定义良好+;标准 是按照C++标准定义的吗?< /P> char* p = 0; std::equal(p, p, p);,c++,visual-studio,stl,C++,Visual Studio,Stl,问题是: 标准是否要求std::equal(begin1,end1,begin2)的实现方式是,如果begin1==end1,则begin1和begin2可以是任何指针,即使是不指向有效内存对象的指针 我假设这是标准的意图,但我还没有找到一个明确的声明 我之所以担心这一点,是因为VisualStudio显然试图检查begin2的“有效性”,即使begin1==end1。这与我对标准要求的理解相矛盾 编辑:以下是VS 2012的代码,我认为它违反了标准: template<class _In

问题是:

标准是否要求
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);
}
模板内联
布尔相等(_InIt1 _First1,_InIt1 _Last1,_InIt2 _First2)
{//将[_Last1,_Last1)与[First2,…]进行比较
_调试范围(_First1,_Last1);
_调试指针(_First2);
返回(_Equal1(_未选中(_First1),_未选中(_Last1),_First2,_已选中(_First2));
}
模板内联
void(调试)指针(常量*),(Dbfile)(t)文件(t),(Dbline)(t)行)
{//非奇异性的测试迭代器,常量指针
如果(_First==0)
_调试错误2(“无效的空指针”,\u文件,\u行);
}

所以我们有25.2.1/1,其中说:

返回:如果对于[first1,last1]范围内的每个迭代器i 以下相应条件成立:*i==*(first2+(i- first1)),pred(*i,*(first2+(i-first1))!=false

否则,, 返回false

在您的例子中,范围[0,0]中没有迭代器,因此该范围中的“每个”迭代器都通过了测试,但不应该进行实际测试(因为要测试的范围中不存在迭代器)


在我看来,这像是VisualStudio的一个bug。

通过您的更新,很明显这不是违反标准,而是一个调试检查。如果您在发布模式下编译它,这些检查不会运行,并且函数与标准的描述相匹配


在调试模式下使用这些信息很有用,因为它将帮助您跟踪一些难以发现的bug。

正如@Zac指出的,这项检查是Visual Studio以安全的名义过于迂腐。如果您希望Visual Studio甚至在调试版本中更严格地遵守标准,您可以通过设置宏。

C++11标准在24.2.1/5中规定“[i,i)是一个空范围”

然而,在24.2.1/5中,它首先暗示0必须是奇异值,然后声明“大多数表达式的结果对于奇异值是未定义的”。然后它列出了未定义行为的例外情况,但不包括比较

因此,可能无法定义比较奇异迭代器是否相等,因此无法计算[i,i]

运行时错误发生在名为_Equal1()的函数中,这一事实也表明了这一点

我认为这个标准在这方面是模糊的,我根本不确定这是VisualStudio2012中的一个bug


在“1213.未指定有效和单数迭代器的含义”一章中,这种混淆也很有趣…

我认为这是定义良好的。@chris我不这么认为。“迭代器”无效,因此这是未定义的行为。您必须先检查p是否为非空。@NeilKirk:它们不是无效的;只是不可取消引用。您仍然可以将
begin1
end1
进行比较,因此该算法是定义良好的,因为它只会进行比较,而不会尝试取消引用任何内容。@NeilKirk:它是一个有效的指针,因此是一个有效的迭代器。它是单数的,不可取消引用,但仍然可以与另一个空指针比较,因此
[null,null)
是一个有效的范围。@NeilKirk:我不知道你为什么这么说,或者你认为“valid”在这个上下文中是什么意思。它是一个单数迭代器(如C++11 24.2.1/5所述),但它与自身比较相等,因此可从自身访问(如24.2.1/6所定义),因此与自身形成有效(空)范围(如24.2.1/7所定义)。此函数的唯一要求是两个输入范围有效;无论Microsoft怎么想,由两个空指针组成的空范围都满足该要求。这可能不是错误,而是不同的解释。也就是说,检入范围[first,last]意味着存在范围。因为[0,0)没有元素,没有范围,因此是无效输入。@Zac和其他任何算法都没有阻止您传递空范围的限制。为什么会有不同?@ShafikYaghmour与之对应的是传递“有效”的内容不可转换的迭代器。例如:容器端,即一些向量
v.end()
。传递
std::equal(v.end(),v.end(),p)
最好工作。我同意马克对这个问题的回答。这应该是可行的,而VS是相当迂腐的。@ZacHowland:标准非常明确:范围不为空是没有前提的,这里的规范明确要求它在为空时返回
false
。@ZacHowland:是的,对不起,我写了
false
当我指的是
true
时。我的观点是,它对任何有效的输入范围都有很好的定义,包括像这样的空范围。我不同意。他们检查太多。这妨碍了完全正确和正常的代码。他们可以轻松地修改他们的调试工具,使其符合标准,并且仍然捕获nul当范围不为空时,l指针。我很确定它可能只是一个bug,或者是一个“thinko”。从代数的角度来看(我相信,从标准的角度来看),作为em的一部分传递不可引用的指针并没有错误或错误