【问题标题】:Can a one past the element pointer that compares equal to a valid pointer be dereferenced?可以取消引用比较等于有效指针的元素指针吗?
【发布时间】:2020-08-01 17:57:05
【问题描述】:

在 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)吗?

【问题讨论】:

    标签: c language-lawyer


    【解决方案1】:

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

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

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

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

    【讨论】:

    • “一些编译器有指针出处的概念” 听起来很有趣,你能说更多吗?哪些编译器可以做到这一点?
    • @HolyBlackCat 请参阅 this question 我几年前发布的。
    • 感谢您的回答。你碰巧知道 C++ 是如何介绍这个的吗?我避免将其标记为 C++ 并引用其标准,因为一般来说,这里的用户会质疑 C/C++ 问题。我想它可能会得出相同的结论,但在这一点上似乎不太明确。
    • @pepper_chico 在 C++ 中,* 期望它的参数指向一个对象或函数,因此超出末尾的指针不适合。它确实没有 C 语言那么明确。
    • @LanguageLawyer 我实际上想知道它是否也具有与插图中相同的指针相等保证,而不仅仅是取消引用方面(这是一个结束的极端情况)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多