This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Ready status.
std::barrierSection: 32.9.3.3 [thread.barrier.class] Status: Ready Submitter: Jiang An Opened: 2023-03-02 Last modified: 2026-09-11
Priority: 3
View all issues with Ready status.
Discussion:
32.9.3.3 [thread.barrier.class]/5 currently says:
[…]is_nothrow_invocable_v<CompletionFunction&>shall betrue.
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.
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.
Modify 32.9.3.3 [thread.barrier.class] as indicated:
-5-
CompletionFunctionshall meet the Cpp17MoveConstructible (Table 32) and Cpp17Destructible (Table 36) requirements. Instantiation ofbarrier<CompletionFunction>is ill-formed ifis_nothrow_invocable_v<CompletionFunction&>is nottrue.is_nothrow_invocable_v<CompletionFunction&>shall betrue
Option B: Clarify that we impose a no-throw precondition here, whose violation causes UB.
Modify 32.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:
(3.1) — Invokes the completion function, equivalent to
completion(). If any invocation to the completion function throws an exception, the behavior is undefined.(3.2) — Unblocks all threads that are blocked on the phase synchronization point.
[…]
-5-CompletionFunctionshall meet the Cpp17MoveConstructible (Table 32) and Cpp17Destructible (Table 36) requirements.is_nothrow_invocable_v<CompletionFunction&>shall betrue.
[2023-03-22; Jonathan provides improved wording]
This wording is relative to N4928.
Modify 32.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:
(3.1) — Invokes the completion function, equivalent to
completion(); if that invocation exits via an exception, the functionstd::terminateis invoked.(3.2) — Unblocks all threads that are blocked on the phase synchronization point.
[…]
-5-
CompletionFunctionshall meet the Cpp17MoveConstructible (Table 32) and Cpp17Destructible (Table 36) requirements.A program that instantiatesis_nothrow_invocable_v<CompletionFunction&>shall betrue.barrier<CompletionFunction>is ill-formed ifis_invocable_v<CompletionFunction&>isfalse.
[2026-09-11; Tim provides new wording]
Needs an update to the gigantic "when do we call std::terminate?" note.
[2026-09-11; LWG telecon. Status changed: New → Ready.]
Proposed resolution:
This wording is relative to N5054.
Modify 14.6.2 [except.terminate] as indicated:
-1- Some errors in a program cannot be recovered from, such as when an exception is not handled or a
std::threadobject is destroyed while its thread function is still executing. In such cases, the functionstd::terminate(17.9.5 [exception.terminate]) is invoked.[Note 1: These situations are:
(1.1) — […]
(1.2) — […]
(1.3) — […]
(1.4) — […]
(1.5) — […]
(1.6) — […]
(1.7) — […]
(1.8) — […]
(1.9) — […]
(1.10) — […]
(1.11) — […]
(1.12) — […]
(1.13) — […]
(1.14) — when a callback invocation exits via an exception when requesting stop on a
std::stop_sourceor astd::inplace_stop_source(32.3.5.3 [stopsource.mem], 32.3.9.3 [stopsource.inplace.mem]), or in the constructor ofstd::stop_callbackorstd::inplace_stop_callback(32.3.6.2 [stopcallback.cons], 32.3.10.2 [stopcallback.inplace.cons]) when a callback invocation exits via an exception, or(1.?) — when an invocation of the completion function of a
std::barrierobject (32.9.3.3 [thread.barrier.class]) exits via an exception, or(1.15) — when a
run_loopobject is destroyed that is still in therunningstate (33.12.1 [exec.run.loop]), or(1.16) — […]
(1.17) — […]
(1.18) — […]
(1.19) — […]
— end note ]
Modify 32.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:
(3.1) — Invokes the completion function, equivalent to
completion(); if that invocation exits via an exception, the functionstd::terminateis invoked.(3.2) — Unblocks all threads that are blocked on the phase synchronization point.
[…]
-5-
CompletionFunctionshall meet the Cpp17MoveConstructible (Table 32) and Cpp17Destructible (Table 36) requirements.A program that instantiatesis_nothrow_invocable_v<CompletionFunction&>shall betrue.barrier<CompletionFunction>is ill-formed ifis_invocable_v<CompletionFunction&>isfalse.