考虑这个案例,它来源于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页
比较指针定义如下:
- 如果一个指针表示一个完整对象的地址,而另一个指针表示另一个完整对象的最后一个元素后的地址,则比较的结果是未指定的。
- 否则,如果两个指针都为空,都指向同一个函数,或者都表示同一个地址,则它们比较相等。
x
和y
都没有指向一个完整的对象,它们最初指向数组的元素,这是一个子对象。所以,看起来第一个项目符号不适用于这种情况。所以,第二个项目符号适用于这里,因为y
紧接在x
最初指向的数组之后。所以,比较是true
,对吗?
2条答案
按热度按时间c9qzyr3d1#
“指向”!=“表示”的地址。在第一个项目符号中:
如果一个指针表示一个完整对象的地址.
(bold矿)
y
并不“指向”一个完整的对象(它指向一个数组元素,也就是它的子对象),但是y
确实“代表了一个完整对象的地址”,因为它在数值上等于整个数组的地址。从你在评论中发布的段落:
[basic.compound]/3
指针类型的值是指向或超过对象末尾的指针,分别表示对象占用的内存([intro.memory])中第一个字节的地址34或对象占用的存储结束后内存中第一个字节的地址。
zc0qhyus2#
指向数组第一个元素的指针是“完整对象的地址”,如果该数组不包含在任何其他对象中。
文本确实适用于该情况。比较具有未指定的行为。
必须指定,因为这些选项都不合理:
Unspecified是最好的。这意味着比较要么是true要么是false,但实现不必指定如何做出选择。因此,它可以自然地留给机会:如果对象以该顺序连续且紧凑地分配,则结果为true,否则为否。