可以取消引用与有效指针比较的元素指针之后的指针吗?

pep*_*ico 4 c language-lawyer

在 C18 中,我们有:

§ 6.5.9p10

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

所以对于int a[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}},我们可以有a[1] == a[0] + 2

结果能保证*(a[1]) == *(a[0] + 2)吗?

dbu*_*ush 6

这是容许取消引用这样一个指针,即使它比较等于另一个有效的指针。

关于+运算符的第 6.5.6p8 节指出:

当具有整数类型的表达式与指针相加或相减时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向与原始元素的元素偏移量,使得结果和原始数组元素的下标之差等于整数表达式。换句话说,如果表达式P指向数组对象的第 i 个元素,则表达式(P)+N (等价地,N+(P))和(P)-N(其中N具有值n)分别指向第i+n个和i?n- 数组对象的第 -th 个元素,前提是它们存在。此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向数组对象最后一个元素后的位置,如果表达式Q指向数组对象最后一个元素后的位置,则表达式(Q)-1指向最后一个元素数组对象。如果指针操作数和结果都指向同一个数组对象的元素,或者数组对象的最后一个元素之后,求值不会产生溢出;否则,行为未定义。 如果结果指向数组对象的最后一个元素,则不应将其用作*被评估的一元运算符的操作数

与此相关的是,一些编译器具有指针出处的概念,这意味着它在内部跟踪指针的来源。这样做的结果是,如果两个不相关的变量在内存中相邻,将一个的地址与另一个的地址进行比较将始终评估为假,即使地址相同。