This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

3898. Possibly unintended preconditions for completion functions of std::barrier

Section: 33.9.3.3 [thread.barrier.class] Status: New Submitter: Jiang An Opened: 2023-03-02 Last modified: 2023-03-22

Priority: 3

View all issues with New status.

Discussion:

33.9.3.3 [thread.barrier.class]/5 currently says:

[…] is_nothrow_invocable_v<CompletionFunction&> shall be true.

This requirement introduces a kind of undefined behavior and permits implementation divergence. Currently MSVC STL enforces the requirement, while libstdc++ and libc++ don't.

If implementation divergence is not intended, I don't think it makes much sense to introduce UB in this way. I guess we should either strengthen the requirement to require well-formedness affection or relax it.

[2023-03-22; Reflector poll]

Set priority to 3 after reflector poll.

Previous resolution [SUPERSEDED]:

This wording is relative to N4928.

[Drafting Note: Two mutually exclusive options are prepared, depicted below by Option A and Option B, respectively.]

Option A: Effectively impose a Mandates: requirement.

  1. Modify 33.9.3.3 [thread.barrier.class] as indicated:

    -5- CompletionFunction shall meet the Cpp17MoveConstructible (Table 32) and Cpp17Destructible (Table 36) requirements. Instantiation of barrier<CompletionFunction> is ill-formed if is_nothrow_invocable_v<CompletionFunction&> is not trueis_nothrow_invocable_v<CompletionFunction&> shall be true.

Option B: Clarify that we impose a no-throw precondition here, whose violation causes UB.

  1. Modify 33.9.3.3 [thread.barrier.class] as indicated:

    -3- The phase completion step that is executed at the end of each phase has the following effects:

    1. (3.1) — Invokes the completion function, equivalent to completion(). If any invocation to the completion function throws an exception, the behavior is undefined.

    2. (3.2) — Unblocks all threads that are blocked on the phase synchronization point.

    […]

    -5- CompletionFunction shall meet the Cpp17MoveConstructible (Table 32) and Cpp17Destructible (Table 36) requirements. is_nothrow_invocable_v<CompletionFunction&> shall be true.

[2023-03-22; Jonathan provides improved wording]

Proposed resolution:

This wording is relative to N4928.

  1. Modify 33.9.3.3 [thread.barrier.class] as indicated:

    -3- The phase completion step that is executed at the end of each phase has the following effects:

    1. (3.1) — Invokes the completion function, equivalent to completion(); if that invocation exits via an exception, the function std::terminate is invoked.

    2. (3.2) — Unblocks all threads that are blocked on the phase synchronization point.

    […]

    -5- CompletionFunction shall meet the Cpp17MoveConstructible (Table 32) and Cpp17Destructible (Table 36) requirements. is_nothrow_invocable_v<CompletionFunction&> shall be true. A program that instantiates barrier<CompletionFunction> is ill-formed if is_invocable_v<CompletionFunction&> is false.