Title
Possibly unintended preconditions for completion functions of std::barrier
Status
new
Section
[thread.barrier.class]
Submitter
Jiang An

Created on 2023-03-02.00:00:00 last changed 20 months ago

Messages

Date: 2023-03-22.23:00:59

Proposed resolution:

This wording is relative to N4928.

  1. Modify [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.

Date: 2023-03-15.00:00:00

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

Date: 2023-03-15.00:00:00

[ 2023-03-22; Reflector poll ]

Set priority to 3 after reflector poll.

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 [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 [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.

Date: 2023-03-02.00:00:00

[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.

History
Date User Action Args
2023-03-22 23:00:59adminsetmessages: + msg13487
2023-03-22 22:40:39adminsetmessages: + msg13483
2023-03-04 12:47:21adminsetmessages: + msg13444
2023-03-02 00:00:00admincreate