Skip to content

CWG2668 [expr.await] await-expression is forbidden to appear in the lambda-expression #195

Description

@xmh0511

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

[expr.await] p2 says

An await-expression shall appear only in a potentially-evaluated expression within the compound-statement of a function-body outside of a handler ([except.pre]).

Consider this example

auto f = []()->Task{
   co_await Awaitable{};
}

Grammarly, the await-expression appears in the compound-statement of a lambda-expression rather than the compound-statement of a function-body, even if [expr.prim.lambda.closure] p13

The lambda-expression's compound-statement yields the function-body ([dcl.fct.def]) of the function call operator, but it is not within the scope of the closure type.

Anyway, they are not equivalent in grammar.

Suggested resolution

An await-expression shall appear only in a potentially-evaluated expression within:

  • the compound-statement of a function-body outside of a handler ([except.pre]), or
  • the compound-statement of a lambda-expression

Activity

  1. jensmaurer commented on Dec 17, 2022

    @jensmaurer
    Member

    "outside of a handler" should also apply to the lambda-expression case.

  2. jensmaurer commented on Dec 17, 2022

    @jensmaurer
    Member
  3. changed the title [-][expr.await] await-expression is forbidden to appear in the lambda-expression[/-] [+]CWG2668 [expr.await] await-expression is forbidden to appear in the lambda-expression[/+] on Dec 17, 2022
  4. xmh0511 commented on Dec 18, 2022

    @xmh0511
    Author

    "outside of a handler" should also apply to the lambda-expression case.

    Where does the handler appear in a lambda-expression? The original wording says

    within the compound-statement of a function-body outside of a handler ([except.pre])

    IIUC, it means that the await-expression can only appear within the compound-statement of a function-body, and shouldn't appear in the handler if the function-body is a function-try-block. In other words, the following example is forbidden

    Task fun() try{}catch(...){
       co_await Awaitable{}; // ill-formed
    }

    Conversely, the below code is well-formed

    Task fun(){
       try{}catch(...){
         co_await Awaitable{};
       }
    }

    Since lambda-expression itself does not have a handler component, I don't think "outside of a handler" should also apply to the lambda-expression case.

    Or, does the original wording intend to mean both cases are ill-formed?

  5. jensmaurer commented on Dec 18, 2022

    @jensmaurer
    Member

    Or, does the original wording intend to mean both cases are ill-formed?

    That's my reading. Both cases are "handlers", I think.

  6. xmh0511 commented on Dec 18, 2022

    @xmh0511
    Author

    Or, does the original wording intend to mean both cases are ill-formed?

    That's my reading. Both cases are "handlers", I think.

    Thanks, you're right. I tested the code in GCC and Clang, and they all agree that the await-expression cannot appear within a handler, that is, "or..." is the proper reading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions