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

1089. Unify "Throws: Nothing." specifications

Section: 32 [thread] Status: C++11 Submitter: Howard Hinnant Opened: 2009-03-22 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [thread].

View all issues with C++11 status.

Discussion:

Addresses JP 76 [CD1]

A description for "Throws: Nothing." are not unified.

At the part without throw, "Throws: Nothing." should be described.

Add "Throws: Nothing." to the following.

[ Summit: ]

Pass on to editor.

[ Post Summit: Editor declares this non-editorial. ]

[ 2009-08-01 Howard provided wording: ]

The definition of "Throws: Nothing." that I added is probably going to be controversial, but I beg you to consider it seriously.

In C++ there are three "flow control" options for a function:

  1. It can return, either with a value, or with void.
  2. It can call a function which never returns, such as std::exit or std::terminate.
  3. It can throw an exception.

The above list can be abbreviated with:

  1. Returns.
  2. Ends program.
  3. Throws exception.

In general a function can have the behavior of any of these 3, or any combination of any of these three, depending upon run time data.

  1. R
  2. E
  3. T
  4. RE
  5. RT
  6. ET
  7. RET

A function with no throw spec, and no documentation, is in general a RET function. It may return, it may end the program, or it may throw. When we specify a function with an empty throw spec:

void f() throw();

We are saying that f() is an RE function: It may return or end the program, but it will not throw.

I posit that there are very few places in the library half of the standard where we intend for functions to be able to end the program (call terminate). And none of those places where we do say terminate could be called, do we currently say "Throws: Nothing.".

I believe that if we define "Throws: Nothing." to mean R, we will both clarify many, many places in the standard, and give us a good rationale for choosing between "Throws: Nothing." (R) and throw() (RE) in the future. Indeed, this may give us motivation to change several throw()s to "Throws: Nothing.".

I did not add the following changes as JP 76 requested as I believe we want to allow these functions to throw:

Add a paragraph under 32.6.5.2 [thread.lock.guard] p4:

explicit lock_guard(mutex_type& m);

Throws: Nothing.

Add a paragraph under 32.6.5.4.2 [thread.lock.unique.cons] p6:

explicit unique_lock(mutex_type& m);

Throws: Nothing.

Add a paragraph under 32.7.5 [thread.condition.condvarany] p19, p21 and p25:

template <class Lock, class Rep, class Period> 
  bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);

Throws: Nothing.

template <class Lock, class Duration, class Predicate> 
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& rel_time, Predicate pred);

Throws: Nothing.

template <class Lock, class Rep, class Period, class Predicate> 
  bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);

Throws: Nothing.

[ 2009-10 Santa Cruz: ]

Defer pending further developments with exception restriction annotations.

[ 2010-02-11 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

[ 2010-02-24 Pete moved to Open: ]

A "Throws: Nothing" specification is not the place to say that a function is not allowed to call exit(). While I agree with the thrust of the proposed resolution, "doesn't throw exceptions" is a subset of "always returns normally". If it's important to say that most library functions don't call exit(), say so.

[ 2010 Pittsburgh: ]

Move to Ready except for the added paragraph to 16.3.2.4 [structure.specifications].

Proposed resolution:

Add a paragraph under 32.4.3.7 [thread.thread.static] p1:

unsigned hardware_concurrency();

-1- Returns: ...

Throws: Nothing.

Add a paragraph under 32.7.4 [thread.condition.condvar] p7 and p8:

[Informational, not to be incluced in the WP: The POSIX spec allows only:

[EINVAL]
The value cond does not refer to an initialized condition variable. — end informational]
void notify_one();

-7- Effects: ...

Throws: Nothing.

void notify_all();

-8- Effects: ...

Throws: Nothing.

Add a paragraph under 32.7.5 [thread.condition.condvarany] p6 and p7:

void notify_one();

-6- Effects: ...

Throws: Nothing.

void notify_all();

-7- Effects: ...

Throws: Nothing.