cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2835 [basic.scope.scope] Conflicts between P2169R4 and some standard requirements #476

Open jakubjelinek opened 7 months ago

jakubjelinek commented 7 months ago

Full name of submitter (unless configured in github; will be published with the issue): Jakub Jelínek

Reference (section label): basic.scope.scope]/5, [expr.prim.lambda.capture]/2, [class.mem.general]/5, [basic.scope.block]/2

Link to reflector thread (if any):

Issue description: I've ran into several name-independent declaration related issues.

One is that [expr.prim.lambda.capture]/2 says: "Ignoring appearances in initializers of init-captures, an identifier or this shall not appear more than once in a lambda-capture." Isn't that in conflict with "the variable introduced by an init-capture" being listed as one of the possible name-independent declarations? I.e. is

void foo () { auto c = [_ = 2, _ = 3] () {}; }

supposed to be valid?

Another one is [class.mem.general]/5 says: "A member shall not be declared twice in the member-specification, except that" but non-static data member is also listed as one of the possible name-independent declarations. I.e. is

struct S { int _; int _; };

supposed to be valid?

Another one is that exception for name-independent declaration has been added in [basic.scope.block]/2 so that e.g.

if (int _ = 5) {
  int _ = 6;
} else {
  int _ = 7;
}

is valid, but does that also imply that lookups for after the int = 6; declaration or after int _ = 7; declarations should be ambiguous even when they technically aren't in the same scope?

if (int _ = 5) {
  int _ = 6;
  int k = _; // ambiguous?
} else {
  int _ = 7;
  int l = _; // ambiguous?
}

And last is for [basic.block.scope]/5, static/thread storage duration variables aren't allowed to be name-independent, but for structured bindings it only talks about structured bindings not inhabiting a namespace scope. Is

int a[3];
void foo () {
  static auto [_, _, _] = a;
  thread_local auto [_, _, _] = a;
}

supposed to be valid? clang++ seems to allow multiple name-independent init-captures, the non-static data members as well, doesn't diagnose int k = ; or int l = ; as ambigous and rejects the 2 structured bindings: https://godbolt.org/z/vGrfEcv3j GCC similarly, except that it treats the int k = ; or int l = ; lookups as ambiguous.

Suggested resolution:

jakubjelinek commented 7 months ago

@jicama, @cor3ntin

cpplearner commented 7 months ago

And last is for [basic.block.scope]/5, static/thread storage duration variables aren't allowed to be name-independent, but for structured bindings it only talks about structured bindings not inhabiting a namespace scope.

This part is fixed by CWG2764.

jensmaurer commented 7 months ago

Thanks for noticing these oversights.

CWG2835