【问题标题】:Shall a pointer to an array compare equal to a pointer to its first element?指向数组的指针是否应该等于指向其第一个元素的指针?
【发布时间】:2019-12-28 08:05:13
【问题描述】:

假设我有一个数组int x[10];,并且在我的 C++ 抽象机实现中,指向该数组的指针不等于指向其“第一个”元素的指针(应用数组到指针转换的结果到x) 但比较等于指向“最后一个”元素x[9] 的指针。 IE。 (void*)x == (void*)&xfalse(void*)&x[9] == (void*)&xtrue

这样的实现是否符合要求?我唯一知道它“违反”的是[basic.compound]/4 中的非规范注释:

[注意:数组对象和它的第一个元素不是指针可互转换的,即使它们具有相同的地址。 —— 尾注]

【问题讨论】:

  • 我正在尝试理解您的问题。这是 C++ 合并C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) 的区域,然后扩展了标准,将指针声明为prvalue 类型为"pointer to T"C++ Standard 7.3.2 Array-to-pointer conversion。 C++ 标准明确声明"The result is a pointer to the first element of the array." 那么您的结果有何不同?
  • @DavidC.Rankin 是的,数组到指针转换的结果是指向数组第一个元素的指针。我们可以想象它表示编号为0 的数组元素(用于指针运算)。这个指针是否必须比较等于指向整个数组的指针?直觉上是的,但我不知道有任何规范性的措辞这样说。或者你可以从中推断出的措辞。
  • 在标题中进行比较是不正确的。您实际上是在询问代码(void*)x == (void*)&x。在这种情况下,您将转换结果与void * 进行比较。
  • 上面的7.3.2 C++ Array Pointer Conversion链接应该是这个。
  • 好的,所以你在“如果?”中问这个问题。 C++ 的实现 C++ 7.3.2 的结果是指向最后一个元素而不是第一个元素的指针——“那会符合要求吗?”唯一可以给出的答案是(1)不是对 C++ 标准的当前草案,而是(2)对你的“如果?”是肯定的。自己的实施。除此之外,我仍然很难理解你在问什么。

标签: c++ arrays pointers language-lawyer c++17


【解决方案1】:

参见[basic.compound (6.9.2)]/3:

指针类型的值是指向[...]对象的指针,表示该对象占用的内存中第一个字节的地址。

由于x[0] 是数组的第一个元素(并且数组被指定为没有初始填充),x 的第一个字节必须与x[0] 的第一个字节相同。

在 [conv.ptr]/2 中它说:

“指向 cv T 的指针”类型的纯右值,其中 T 是对象类型,可以转换为“指向 cv void 的指针”类型的纯右值。此转换未更改指针值(6.9.2)

除了(void *)&x 的值表示x 的第一个字节的地址之外,我没有看到任何其他解释方式。

【讨论】:

  • @LanguageLawyer 要清楚,您是否建议 x[9] 可能是数组内存中的第一个元素?
  • 我的答案不是循环。前提是x[0] 是第一个数组元素,从该前提得出的结论是(void *)&x == (void *)&x[0] 必须为真。
  • x&x 进行比较是不正确的。问题是关于 (void *)&x == (void *)&x[0] 的,因此您必须考虑转换为 void * 的行为,我的回答涵盖了这一点。
  • 那么,既然(void *)&x == (void *)&x[0] 的情况得到了证明,并且您同意强制转换没有改变值,那么究竟还有什么问题?
  • “第一个数组元素”是指它占据了数组存储的初始部分。你现在是说你不承认x[0] 表示一个int 子对象占用了数组存储的初始部分?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多