C++ 遍历的幂等性:指针?参考 ?指针

MrA*_*ima 4 c++ pointers reference language-lawyer

我的理解

  • 在 C++ 中,普通值可以使用 转换为指向其自身的指针&value,或通过隐式转换转换为对其自身的引用。

  • 与 Rust 不同,引用并不是实际的一等类型,而只是某些类型声明站点接受的二进制限定符。引用可以透明地使用,就好像它们是它们的裁判一样,隐藏内部指针1。因此,我们可以&refToValue立即获取指向裁判的指针。

问题

如果我将指针转换为引用,再转换回指针,我能保证恢复到原始指针吗?Rust 中就是这种情况,但 Rust 再次将一级引用定义为通过指针抽象的“普通”类型。

// Sample code by @chi
T x;
T* ptr1 = &x;
T& ref = *ptr1;
T* ptr2 = &ref;
assert(ptr1 == ptr2); // Is that always true according to the spec?
Run Code Online (Sandbox Code Playgroud)

1:我知道 C++ 标准不要求将引用实现为指针,但我看不出如何以任何其他方式实现它们(不考虑上下文特定的优化),特别是如果我的最后一个问题的答案是“是的”。

YSC*_*YSC 7

\n

If I convert a pointer, to a reference, back to a pointer, am I guaranteed to get the original pointer back?

\n
T x;\nT* ptr1 = &x;\nT& ref = *ptr1;\nT* ptr2 = &ref;\n
Run Code Online (Sandbox Code Playgroud)\n
\n

Yes.

\n
\n

Full explanation on the initialisations

\n
    \n
  • Per [expr.unary.op]/3.2, T* ptr1 = &x initializes ptr1 as a pointer to T pointing to the designated object (x).
  • \n
\n
\n

The operand of the unary & operator shall be an lvalue of some type T. The result is a prvalue.
\n...
\n(3.2)\nOtherwise, the result has type \xe2\x80\x9cpointer to T\xe2\x80\x9d and points to the designated object ([intro.memory]) or function ([basic.compound]). If the operand names an explicit object member function ([dcl.fct]), the operand shall be a qualified-id.

\n
\n
    \n
  • Per [expr.unary.op]/1 and [dcl.ref]/5, T& ref = *ptr1 initializes ref to refer to a valid object, namely x as *ptr1 performs indirection on ptr1 and yields an lvalue denoting the object to which ptr1 points, namely x.
  • \n
\n
\n

[expr.unary.op]/1 The unary * operator performs indirection. Its operand shall be a prvalue of type \xe2\x80\x9cpointer to T\xe2\x80\x9d, where T is an object or function type. The operator yields an lvalue of type T denoting the object or function to which the operand points.

\n

[dcl.ref]/5 A reference shall be initialized to refer to a valid object or function.

\n
\n
    \n
  • Finally, per [expr.unary.op]/3.2 again, T* ptr2 = &ref initializes ptr2 as a pointer to T pointing to the designated object (x).
  • \n
\n
\n

What about the pointer comparison?

\n\n
\n

A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory ([intro.memory]) occupied by the object35 or the first byte in memory after the end of the storage occupied by the object, respectively.

\n
\n

和[expr.eq]/3.2:

\n
\n

[参考 == 的结果,按照 /1 中的定义]
\nif the pointers are both null, both point to the same function, or both represent the same address, they compare equal.

\n
\n

ptr1意思是,无论和的实际值如何ptr2:

\n
ptr1 == ptr2\n
Run Code Online (Sandbox Code Playgroud)\n

产量true.

\n