我在下面关于 C++ 标准中的 §9.3.1/3 的观察是否正确?

Am I correct in my observation below about §9.3.1/3 in the C++ Standard?

§9.3.1/3(重点是我的):

When an id-expression (5.1) that is not part of a class member access syntax (5.2.5) and not used to form a pointer to member (5.3.1) is used in a member of class X in a context where this can be used (5.1.1), if name lookup (3.4) resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression (5.2.5) using (*this) (9.3.2) as the postfix-expression to the left of the . operator. [ Note: If C is not X or a base class of X, the class member access expression is ill-formed. — end note ] Similarly during name lookup, when an unqualified-id (5.1) used in the definition of a member function for class X resolves to a static member, an enumerator or a nested type of class X or of a base class of X, the unqualified-id is transformed into a qualified-id (5.1) in which the nested-name-specifier names the class of the member function.

上面的注释不应该更具体吗?我的意思是这样的:`如果可能评估 id 表达式并且如果 C 不是 X 或 X 的基数 class,则 class 成员访问表达式格式错误。"

请注意,如果 id-expression 是未计算的操作数,即使 C 不是 X,也不是 X 的基数 class,代码仍然有效,尽管在这种情况下,段落中提到的转换将没有发生。

注释有点含糊,但我认为它的目的是对前一句的最后部分进行注释,好像写成这样:

and if either the id-expression is potentially evaluated or C is X or a base class of X, then:

  • the id-expression is transformed into a class member access expression (5.2.5) using (*this) (9.3.2) as the postfix-expression to the left of the . operator. [ Note: If C is not X or a base class of X, the class member access expression is ill-formed. — end note ]

当这样阅读时,注释是完全正确的。

无论如何,注释不是规范的,所以即使措辞有疑问,也没关系,因为它对任何 C++ 程序或实现没有任何影响:没有程序变得有效或由于本说明的措辞而无效,并且由于本说明,没有实现符合或不符合。在最坏的情况下,就像这里发生的那样,理解标准变得更加困难,导致误解。

正如 Columbo 在评论中提到的那样,实施者的这种误解可能会导致不符合要求的实施,但这不是这里发生的事情。

该注释基本上意味着,如果您使用 C::member 作为变量(而不仅仅是确定其类型、对齐方式或大小),则该程序显然是非良构的。

一个例子是

class C 
{
    int member;
};

class X
{
    void memfun()
    {
        // Note that 'this' can be used here

        C::member = 3; // member is potentially evaluated ([basic.def.odr]/2).
                       // Thus the expression is transformed into 
                       // (*this).member
                       // which is clearly ill-formed.
    }
};

程序格式错误,因为 member 没有任何 "to do" 和 X(它不是 X 的成员或任何基 class 其中)并可能对其进行评估。
引用是适当的(虽然多余)。

但是,为什么 sizeof(C::member) 不是病式的呢?因为 C::member 可能未被评估。

An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof.

和[expr.sizeof]:

The operand is either an expression, which is an unevaluated operand (Clause 5), or a parenthesized type-id.

因此没有转换 id 表达式。

所以这张便条来自 defect report 515 2005 年,当时的措辞不同:

When an id-expression (5.1.1 [expr.prim.general]) that is not part of a class member access syntax (5.2.5 [expr.ref]) and not used to form a pointer to member (5.3.1 [expr.unary.op]) is used in the body of a non-static member function of class X or used in the mem-initializer for a constructor of class X, if name lookup (3.4.1 [basic.lookup.unqual]) resolves the name in the id-expression to a non-static non-type member of some class C, the id-expression is transformed into a class member access expression (5.2.5 [expr.ref]) using (*this) (9.3.2 [class.this]) as the postfix-expression to the left of the . operator. [Note: If C is not X or a base class of X, the class member access expression is ill-formed. —end note]

并且有所演变,注意当前的写法前注意:

or C is X or a base class of X, the id-expression

在这个早期的措辞中没有出现,所以有澄清说明更有意义,在这一点上,说明似乎是多余的。