cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2883 [basic.def.odr] Using captures in lambda bodies always disallowed because odr-usable definition does not account for lambda scopes #523

Open hubert-reinterpretcast opened 3 months ago

hubert-reinterpretcast commented 3 months ago

Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong

Reference (section label): basic.def.odr

Link to reflector thread (if any): N/A

Issue description: https://eel.is/c++draft/basic.def.odr#10 defines odr-usable and has a rule:

If a local entity is odr-used in a scope in which it is not odr-usable, the program is ill-formed.

One of the requirements for a local entity to be odr-usable, is that there are no intervening scopes other than block scopes and function parameter scopes.

Consider:

void f() {
  int x;
  [&] { return x; };
}

There is a lambda scope (https://eel.is/c++draft/basic.scope.lambda) between the block scope of the compound-statement and the definition of x. It follows that the above code is ill-formed (according to the wording).

Consider also:

struct A {
  A() = default;
  A(const A &) = delete;
  constexpr operator int() { return 42; }
};
void f() {
  constexpr A a;
  [=]<typename T, int = a> {};
}

The only reason from the wording for why a is not odr-usable from the default argument (and thus not captured, see https://eel.is/c++draft/expr.prim.lambda.capture#7) is because there is a lambda scope. There is implementation divergence: https://godbolt.org/z/d41381qxM. Behaviours observed include accepting the code, rejecting the code because of the deleted copy constructor, and rejecting the code because a is named from the default template argument.

Suggested resolution: Replace the bullets under https://eel.is/c++draft/basic.def.odr#10.2 with:

t3nsor commented 3 months ago

Surely the third bullet should say "a block scope" or "the outermost block scope", but other than that, makes sense to me.

hubert-reinterpretcast commented 3 months ago

Surely the third bullet should say "a block scope" or "the outermost block scope", but other than that, makes sense to me.

That is copied from existing wording. The use of the definite article "the" is taken to mean the one that certainly arises from the construct.

jensmaurer commented 2 months ago

CWG2883