一个过去的对象结束指针

时间:2014-07-21 06:46:45

标签: c++ c

我知道只有两个指针才会定义指针比较 指向某个地方"进入"分配给同一对象的存储,或者是否 只要它不是,它们就是NULL,或者只是对象的一端 解除引用。

我用"对象"在标准' C'感。

比较两个指针是否有一些特殊的分配 这是 - 每一个 - 超过对象结束而不是 比较一个过去的结束指针和一个派生的指针表达式 引用实际对象。鉴于以下定义:

 char arr[100];
 char *pend = &arr[99];
 char *pa = pend+1;
 char *pb = pend+1;

是保证有意义的比较pa == pb 调用UB是因为 - 既不是-pa也不是pb指向arr。

换句话说,从标准的角度来看,是否存在 比较pa和pb之间的语义差异和比较, 说,pa和&arr[99]+1? 看起来很明显,但是:)

2 个答案:

答案 0 :(得分:6)

这是一个很好的例子,说明为什么你不应该用C和C ++标记你的问题:

对于C,标准涵盖了这一点。

  

6.5.9平等运营商

     

6两个指针比较相等当且仅当两个都是空指针时,两者都是指向同一对象的指针(包括指向对象的指针和开头的子对象)或函数,都是指向一个指针的指针同一个数组对象的最后一个元素,或者一个指向一个数组对象末尾的指针,另一个是指向紧跟第一个数组对象的另一个数组对象的开头的指针在地址空间。

对于C ++,它不是那么清楚:

  

5.10 Equality运算符[expr.eq]

     

1 ==(等于)和!=(不等于)运算符与关系运算符具有相同的语义限制,转换和结果类型,除了它们的优先级和真实性低 - 价值结果。 [注意: a<b == c<d只要truea<b具有相同的真值,就为c<d。 - 结尾注释]可以比较相同类型的指针(指针转换后)是否相等。两个相同类型的指针比较相等,当且仅当它们都为空时,都指向相同的函数,或两者都代表相同的地址(3.9.2)

从技术上讲,我不知道标准要求两个过去的指针代表相同的地址。我可以找到标准要求对象具有地址的位置,并且&运算符返回该特定地址(因此将地址取两次产生相同的指针值),但是过去的结束指针不指向到一个对象,所以不适用。它们可能不同,只要减去工作就可以回到相同的数组库。

但实际上,你不必担心这一点,它将在C ++和C中一起使用。

更新:根据JohnB的答案和那里的评论,C ++标准可能打算更明确地要求这一点,但它确实需要间接地提供它。

答案 1 :(得分:2)

在C ++中,只保证前向迭代器

  

24.2.5转发迭代器

     

类或指针类型X满足前向迭代器的要求   [...] X型物体提供多次通过保证,如下所述。   [...]

     

前向迭代器的==域是迭代器的域   相同的基础序列。 [...]

     

两   类型为X的可解引用迭代器a和b提供多次传递   保证如果:

     

- a == b表示++ a == ++ b和[...]

从24.4.1(指针的iterator_traits的特化)得出,指针是随机访问迭代器,因此转发迭代器。

或者,但也许不那么令人信服,对于数组,如果(p+1) == (q+1)p指向数组的最后一个元素,则可以隐式地推断出q,来自下面的措辞:

  

5.7添加剂运算符   [...]   此外,如果表达式P指向数组的最后一个元素   对象,表达式(P)+1指向一个过去的最后一个元素   数组对象,如果表达式Q指向最后一个元素   对于数组对象,表达式(Q)-1指向的最后一个元素   数组对象。

这隐含地假设有一个明确定义的地址代表&#34;一个超过最后一个元素&#34;。 (数组是线性的,&#34;一个超过最后一个元素&#34;包括线性事物数组被扩展的虚构,线性事物的自然延伸也是线性的,所以只有一件事情&#34;一件事超过最后一个元素&#34; 。请注意标准在&#34;一个过去最后一个元素&#34;和简单&#34之间的区别;过去最后一个元素&#34;其他地方。)