c++ 此指针比较是否未指定或等效?

gupuwyp2  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(178)

考虑这个案例,它来源于https://www.ralfj.de/blog/2018/07/24/pointers-and-bytes.html

int main(){
    auto x = new int[8];
    auto y = new int[8];
    y[0] = 42;
    auto x_ptr = x+8; // one past the end
    if (x_ptr == &y[0]){
         // ...
    }
}

字符串
现在,假设x和y被分配到彼此相邻的位置,y具有较高的地址。
根据[表达式等式]第3页
比较指针定义如下:

  • 如果一个指针表示一个完整对象的地址,而另一个指针表示另一个完整对象的最后一个元素后的地址,则比较的结果是未指定的。
  • 否则,如果两个指针都为空,都指向同一个函数,或者都表示同一个地址,则它们比较相等。

xy都没有指向一个完整的对象,它们最初指向数组的元素,这是一个子对象。所以,看起来第一个项目符号不适用于这种情况。所以,第二个项目符号适用于这里,因为y紧接在x最初指向的数组之后。所以,比较是true,对吗?

c9qzyr3d

c9qzyr3d1#

“指向”!=“表示”的地址。在第一个项目符号中:
如果一个指针表示一个完整对象的地址.
(bold矿)
y并不“指向”一个完整的对象(它指向一个数组元素,也就是它的子对象),但是y确实“代表了一个完整对象的地址”,因为它在数值上等于整个数组的地址。
从你在评论中发布的段落:[basic.compound]/3
指针类型的值是指向或超过对象末尾的指针,分别表示对象占用的内存([intro.memory])中第一个字节的地址34或对象占用的存储结束后内存中第一个字节的地址。

zc0qhyus

zc0qhyus2#

指向数组第一个元素的指针是“完整对象的地址”,如果该数组不包含在任何其他对象中。
文本确实适用于该情况。比较具有未指定的行为。
必须指定,因为这些选项都不合理:

  • 使它不明确。为什么?谁需要另一把脚枪。
  • 问题是,实现必须记录行为是如何发生的,揭示分配器在所有情况下如何工作的所有实现细节。
  • 让它定义好是不可能的。让它总是为假意味着对象不能被压缩分配:在每个对象之后至少要浪费一个字节的空间(加上对齐),以确保“一个过去”指针不是任何其他对象的地址。让它总是为真是不可能的;它不可能对所有对象对都为真。

Unspecified是最好的。这意味着比较要么是true要么是false,但实现不必指定如何做出选择。因此,它可以自然地留给机会:如果对象以该顺序连续且紧凑地分配,则结果为true,否则为否。

相关问题