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

### 2080. Specify when `once_flag` becomes invalid

Section: 33.6.7 [thread.once] Status: C++14 Submitter: Nicolai Josuttis Opened: 2011-08-30 Last modified: 2016-01-28

Priority: Not Prioritized

View all issues with C++14 status.

Discussion:

In function `call_once` 33.6.7.2 [thread.once.callonce] paragraph 4 and 5 specify for `call_once()`:

> Throws: `system_error` when an exception is required (33.2.2 [thread.req.exception]), or any exception thrown by `func`.

> Error conditions:
> - `invalid_argument` — if the `once_flag` object is no longer valid.

However, nowhere in 33.6.7 [thread.once] is specified, when a once-flag becomes invalid.

As far as I know this happens if the flag is used for different functions. So we either have to have to insert a sentence/paragraph in

> 30.4.4.2 Function call_once [thread.once.callonce]

or

> 30.4.4 Call once [thread.once]

explaining when a `once_flag` becomes invalidated or we should state as error condition something like:

- `invalid_argument` — if the `func` used in combination with the `once_flag` is different from a previously passed `func` for the same `once_flag`

Anthony Williams:

> A `once_flag` is invalidated if you destroy it (e.g. it is an automatic object, or heap allocated and deleted, etc.)

> If the library can detect that this is the case then it will throw this exception. If it cannot detect such a case then it will never be thrown.

Jonathan Wakely:

> I have also wondered how that error can happen in C++, where the type system will reject a non-callable type being passed to `call_once()` and should prevent a `once_flag` being used after its destructor runs.

> If a `once_flag` is used after its destructor runs then it is indeed undefined behaviour, so implementations are already free to throw any exception (or set fire to a printer) without the standard saying so.

> My assumption was that it's an artefact of basing the API on pthreads, which says:

> > The `pthread_once()` function may fail if:

> > `[EINVAL]` If either `once_control` or `init_routine` is invalid.

Pete Becker:

> Yes, probably. We had to clean up several UNIXisms that were in the original design.

[2012, Kona]

Remove error conditions, move to Review.

[2012, Portland: move to Tentatively Ready]

Concurrency move to Ready, pending LWG review.

LWG did not have time to perform the final review in Portland, so moving to tentatively ready to reflect the Concurrency belief that the issue is ready, but could use a final inspection from library wordsmiths.

[2013-04-20 Bristol]

Proposed resolution:

This wording is relative to N3337.

1. Change 33.6.7.2 [thread.once.callonce] as indicated:

   >     template<class Callable, class ...Args>
   >     void call_once(once_flag& flag, Callable&& func, Args&&... args);

   > > […]

   > > -4- Throws: `system_error` when an exception is required (30.2.2), or any exception thrown by `func`.

   > > -5- Error conditions:
   > > - `invalid_argument` — if the `once_flag` object is no longer valid.