Home > Net >  Is it legal for a lambda to odr-use this or a not captured entity with automatic storage duration in
Is it legal for a lambda to odr-use this or a not captured entity with automatic storage duration in

Time:09-05

[expr.prim.lambda.capture]/8 of the final draft of C 17 N4659:

An entity is captured if it is captured explicitly or implicitly. An entity captured by a lambda-expression is odr-used in the scope containing the lambda-expression. If *this is captured by a local lambda expression, its nearest enclosing function shall be a non-static member function. If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses this or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression. If a lambda-expression captures an entity and that entity is not defined or captured in the immediately enclosing lambda expression or function, the program is ill-formed.

However, [expr.prim.lambda.capture]/8 of the final draft of C 20 N4861:

An entity is captured if it is captured explicitly or implicitly. An entity captured by a lambda-expression is odr-used ([basic.def.odr]) in the scope containing the lambda-expression. [ Note: As a consequence, if a lambda-expression explicitly captures an entity that is not odr-usable, the program is ill-formed ([basic.def.odr]). — end note ]

It removes the description that this or such entities should be captured in this case. Does it mean they don't need to be captured (of course, that's not possible)? Or is it explained elsewhere?

CodePudding user response:

For future reference, I find this GitHub repository https://github.com/cplusplus/draft is useful in finding out how things changed between different C standards. In particular, I found this commit using git blame, which is the result of P0588R1: Simplifying implicit lambda capture (to resolve CWG 1632. Lambda capture in member initializers)

It seems that this has been moved to [basic.def.odr]p9 in N4861:

A local entity ([basic.pre]) is odr-usable in a declarative region ([basic.scope.declarative]) if:

  • (9.1) 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
  • (9.2) for each intervening declarative region ([basic.scope.declarative]) between the point at which the entity is introduced and the region (where *this is considered to be introduced within the innermost enclosing class or non-lambda function definition scope), either:
    • (9.2.1) the intervening declarative region is a block scope, or
    • (9.2.2) the intervening declarative region is the function parameter 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 declarative region.

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

(emphasis mine)

So for an automatic variable or this to be odr-usable, they need to be captured.

  • Related