This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[Accepted as a DR at the June, 2024 meeting.]
(From submission #523.)
Consider:
void f() {
int x;
[&] {
return x; // #1
};
}
The odr-use of x is ill-formed, because x is not odr-usable in that scope, because there is a lambda scope (6.4.5 [basic.scope.lambda]) between #1 and the definition of x.
A more involved example exhibits implementation divergence:
struct A {
A() = default;
A(const A &) = delete;
constexpr operator int() { return 42; }
};
void f() {
constexpr A a;
[=]<typename T, int = a> {}; // OK, not odr-usable from a default template argument, and not odr-used
}
Proposed resolution (approved by CWG 2024-05-31):
Change in 6.3 [basic.def.odr] paragraph 10 as follows:
A local entity (6.1 [basic.pre]) is odr-usable in a scope (6.4.1 [basic.scope.scope]) if:If a local entity is odr-used in a scope in which it is not odr-usable, the program is ill-formed.
- either the local entity is not *this, or an enclosing class or non-lambda function parameter scope exists and, if the innermost such scope is a function parameter scope, it corresponds to a non-static member function, and
- for each intervening scope (6.4.1 [basic.scope.scope]) between the point at which the entity is introduced and the scope (where *this is considered to be introduced within the innermost enclosing class or non-lambda function definition scope), either:
- the intervening scope is a block scope, or
- the intervening scope is the function parameter scope of a lambda-expression, or
- the intervening scope is the lambda scope of a lambda-expression that has a simple-capture naming the entity or has a capture-default, and the block scope of the lambda-expression is also an intervening scope.