cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2902 [expr.prim.id.general] Transformation of id-expressions to non-static non-type members in class scope #553

Open ckwastra opened 2 weeks ago

ckwastra commented 2 weeks ago

Full name of submitter: Vincent X

Reference: [expr.prim.id.general]

Issue description: P1787R6 effectively relaxed the constraints on the transformation of id-expressions (to non-static non-type members) in class scope into class member access expressions, such that they may be transformed even if the expression this is not allowed in the context. Consider:

struct A {
  int x;
  int a[sizeof(x)]; // (1)
  decltype(x) f();  // (2)
};

Under the current rules of [expr.prim.id.general]/2, both expressions of x in (1) and (2) are transformed into (*this).x, making the declarations ill-formed. This is because P1787R6 removed the old constraint (as referenced in #[class.mfct.non-static]):

[...] in a context where this can be used [...]

Suggested resolution: Reintroduce the constraint where appropriate.

t3nsor commented 2 weeks ago

I suspect the reason why P1787R6 changed the wording in this area may have had something to do with the issue where you can't figure out whether or not you're allowed to use this until you see the full declarator (note 2 in [expr.prim.this]), so the old wording "in a context where this can be used" was imprecise.

Perhaps add a new bullet before [expr.prim.id.general]/2.1:

If an id-expression E denotes a non-static non-type member of some class C at a point where the current class ([expr.prim.this]) is X and

  • The type of the expression this is defined by [expr.prim.this], and
  • E is potentially evaluated or C is X or a base class of X, and
  • [...]

the id-expression is transformed into a class member access expression using (*this) as the object expression. [...]

jensmaurer commented 2 weeks ago

CWG2902