<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1487: Clock related operations exception specifications conflict</title>
<meta property="og:title" content="Issue 1487: Clock related operations exception specifications conflict">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1487.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++11">C++11</a> status.</em></p>
<h3 id="1487"><a href="lwg-defects.html#1487">1487</a>. Clock related operations exception specifications conflict</h3>
<p><b>Section:</b> 32.4.5 <a href="https://wg21.link/thread.thread.this">[thread.thread.this]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Switzerland <b>Opened:</b> 2010-08-25 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#thread.thread.this">issues</a> in [thread.thread.this].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p><b>Addresses CH-25</b></p>
<p>
Clock related operations are currently not required not to
throw. So "Throws: Nothing." is not always true.
</p>
<p><i>[
Resolution proposed by ballot comment:
]</i></p>

<blockquote><p>
Either require clock related operations not to throw
(in 20.10) or change the Throws clauses in 30.3.2.
Also possibly add a note that <code>abs_time</code> in the past
or negative <code>rel_time</code> is allowed.
</p></blockquote>

<p><i>[2011-02-10: Howard Hinnant provides a resolution proposal]</i></p>


<p><i>[Previous proposed resolution:]</i></p>

<ol>
<li>
<p>Change the Operational semantics of <code>C1::now()</code> in 30.3 <a href="https://wg21.link/time.clock.req">[time.clock.req]</a>, 
Table 59 &mdash; <code>Clock</code> requirements as follows:
</p>

<blockquote>
<table border="1">
<caption>Table 59 &mdash; <code>Clock</code> requirements</caption>
<tr>
<th>
Expression
</th>

<th>
Return type
</th>

<th>
Operational semantics
</th>

</tr>

<tr>
<td><code>C1::now()</code></td>

<td><code>C1::time_point</code></td>

<td>Returns a <code>time_point</code> object<br/>
representing the current point in time.<br/>
<ins>Shall not throw an exception.</ins></td>
</tr>

</table>
</blockquote>


</li>
</ol>

<p><i>[2011-02-19: Daniel comments and suggests an alternative wording]</i></p>


<p>Imposing the no-throw requirement on <code>C1::now()</code> of any clock time
is an overly radical step: It has the indirect consequences that representation
types for <code>C1::rep</code> can never by types with dynamic memory managment,
e.g. my <code>big_int</code>, which are currently fully supported by the time
utilities. Further-on this strong constraint does not even solve the problem
described in the issue, because we are still left with the fact that any
of the arithmetic operations of <code>C1::rep</code>, <code>C1::duration</code>,
and <code>C1::time_point</code> may throw exceptions.
</p>
<p>The alternative proposal uses the following strategy: The general <code>Clock</code>
requirements remain untouched, but we require that any functions of the library-provided
clocks from sub-clause 30.7 <a href="https://wg21.link/time.clock">[time.clock]</a> and their associated types shall not
throw exceptions. Second, we replace existing <code>noexcept</code> specifications of
functions from Clause 30 that depend on durations, clocks, or time points by wording that
clarifies that these functions can only throw, if the operations of user-provided durations,
clocks, or time points used as arguments to these functions throw exceptions.
</p>

<p><i>[2011-03-23 Daniel and Peter check and simplify the proposed resolution resulting in this paper]</i></p>


<p>There is an inherent problem with <code>std::time_point</code> that it doesn't seem to have an equivalent value 
for <code>((time_t)-1)</code> that gets returned by C's <code>time()</code> function to signal a problem, e.g., because 
the underlying hardware is unavailable. After a lot of thinking and checks we came to the resolution that 
<code>timepoint::max()</code> should be the value to serve as a value signaling errors in cases where we
prefer to stick with no-throw conditions. Of-course, user-provided representation types don't need to
follow this approach if they prefer exceptions to signal such failures.
<p/>
the functions <code>now()</code> and <code>from_time_t()</code> can remain <code>noexcept</code> with the solution to 
return <code>timepoint::max()</code> in case the current time cannot be determined or <code>(time_t)-1</code> is passed 
in, respectively.
<p/>
Based on the previous proposed solution to LWG 1487 we decided that the new <code>TrivialClock</code> requirements 
should define that <code>now()</code> mustn't throw and return <code>timepoint::max()</code> to signal a problem. That 
is in line with the C standard where <code>(time_t)-1</code> signals a problem. Together with a fix to a - we assumed - 
buggy specifcation in 20.11.3 p2 which uses "happens-before" relationship with something that isn't any action:
</p>
<blockquote><p>
2 In Table 59 <code>C1</code> and <code>C2</code> denote clock types. <code>t1</code> and <code>t2</code> are values returned by 
<code>C1::now()</code> where the call returning <code>t1</code> happens before (1.10) the call returning <code>t2</code> and 
both of these calls happen before <code>C1::time_point::max()</code>. 
</p></blockquote>

<p><i>[2011-03-23 Review with Concurrency group suggested further simplifications and Howard pointed out, that
we do not need time_point::max() as a special value.]</i></p>


<p>also the second "happens before" will be changed to "occurs before" in the english meaning. this is
to allow a steady clock to wrap.
<p/>
Peter updates issue accordingly to discussion.
</p>

<p><i>[Note to the editor: we recommend removal of the following redundant paragraphs in 
 32.7.5 <a href="https://wg21.link/thread.condition.condvarany">[thread.condition.condvarany]</a> p. 18 to p. 21, p. 27, p. 28, p. 30, and p. 31 that are 
defining details for the wait functions that are given by the <i>Effects</i> element. 
]</i></p>


<p><i>[Note to the editor: we recommend removal of the following redundant paragraphs in 
32.7.4 <a href="https://wg21.link/thread.condition.condvar">[thread.condition.condvar]</a>: p24-p26, p33-p34, and p36-p37 that are defining details for the 
<code>wait_for</code> functions. We believe these paragraphs are redundant with respect to the <i>Effects</i> clauses that 
define semantics based on <code>wait_until</code>. An example of such a specification is the <code>wait()</code> with a predicate.
]</i></p>



<p id="res-1487"><b>Proposed resolution:</b></p>

<ol>
<li><p>Change p2 in 20.11.3 [time.clock.req] as follows</p>
<blockquote><p>
2 In Table 59 <code>C1</code> and <code>C2</code> denote clock types. <code>t1</code> and 
<code>t2</code> are values returned by <code>C1::now()</code> where the call returning <code>t1</code> 
happens before (1.10) the call returning <code>t2</code> and both of these calls <del>happen</del>
<ins>occur</ins> before <code>C1::time_point::max()</code>. 
<ins>[ <i>Note</i>: This means <code>C1</code> didn't wrap around between <code>t1</code> and <code>t2</code> &mdash; <i>end note</i> ]</ins>
</p></blockquote>
</li>

<li><p>Add the following new requirement set at the end of sub-clause 30.3 <a href="https://wg21.link/time.clock.req">[time.clock.req]</a>: [<i>Comment</i>:
This requirement set is <strong>intentionally</strong> incomplete. The reason for
this incompleteness is the based on the fact, that if we would make it right for C++0x, we would end up defining
something like a complete <code>ArithmeticLike</code> concept for <code>TC::rep</code>, <code>TC::duration</code>, and <code>TC::time_point</code>. 
But this looks out-of scope for C++0x to me. The effect is that we essentially do not exactly say, which arithmetic 
or comparison operations can be used in the time-dependent functions from Clause 30, even though I expect that
all declared functions of <code>duration</code> and <code>time_point</code> are well-formed and well-defined. &mdash; <i>end comment</i>]</p>
<blockquote><p>
3 [ <i>Note</i>: the relative difference in durations between those reported by a given clock and the SI definition is
a measure of the quality of implementation. &mdash; <i>end note</i> ]
</p></blockquote>

<blockquote><p>
<ins>? A type <code>TC</code> meets the <code><i>TrivialClock</i></code> requirements if:</ins>
</p>
<ul>
<li><p>
<ins><code>TC</code> satisfies the <code>Clock</code> requirements (30.3 <a href="https://wg21.link/time.clock.req">[time.clock.req]</a>),</ins>
</p></li>
<li><p>
<ins>the types <code>TC::rep</code>, <code>TC::duration</code>, and <code>TC::time_point</code> satisfy 
the requirements of <code>EqualityComparable</code> ( [equalitycomparable]), <code>LessThanComparable</code> 
( [lessthancomparable]), <code>DefaultConstructible</code> ( [defaultconstructible]), 
<code>CopyConstructible</code> ( [copyconstructible]), <code>CopyAssignable</code> ( [copyassignable]), 
<code>Destructible</code> ( [destructible]), and of numeric types ([numeric.requirements]) [<i>Note</i>: This means in 
particular, that operations of these types will not throw exceptions &mdash; <i>end note</i> ],</ins>
</p></li>
<li><p>
<ins>lvalues of the types <code>TC::rep</code>, <code>TC::duration</code>, and <code>TC::time_point</code> are swappable 
(16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a>),</ins>
</p></li>
<li><p>
<ins>the function <code>TC::now()</code> does not throw exceptions, and</ins>
</p></li>
<li><p>
<ins>the type <code>TC::time_point::clock</code> meets the <code>TrivialClock</code> requirements, recursively.</ins>
</p></li>
</ul>
</blockquote>
</li>

<li>
<p>Modify 30.7 <a href="https://wg21.link/time.clock">[time.clock]</a> p. 1 as follows:</p>

<blockquote><p>
1 - The types defined in this subclause shall satisfy the <code><ins>Trivial</ins>Clock</code> requirements (20.11.1). 
</p></blockquote>
</li>

<li>
<p>Modify 30.7.2 <a href="https://wg21.link/time.clock.system">[time.clock.system]</a> p. 1, class <code>system_clock</code> synopsis, as follows:</p>

<blockquote><pre>
class system_clock {
public:
  typedef <i>see below</i> rep;
  typedef ratio&lt;<i>unspecified</i> , <i>unspecified</i> &gt; period;
  typedef chrono::duration&lt;rep, period&gt; duration;
  typedef chrono::time_point&lt;system_clock&gt; time_point;
  static const bool is_monotonic is_steady = <i>unspecified</i>;
  static time_point now() <ins>noexcept</ins>;
  // Map to C API
  static time_t to_time_t (const time_point&amp; t) <ins>noexcept</ins>;
  static time_point from_time_t(time_t t) <ins>noexcept</ins>;
};
</pre></blockquote>

</li>

<li>
<p>Modify the prototype declarations in 30.7.2 <a href="https://wg21.link/time.clock.system">[time.clock.system]</a> p. 3 + p. 4 as indicated (This 
edit also fixes the miss of the <code>static</code> specifier in these prototype declarations):</p>

<blockquote><pre>
<ins>static</ins> time_t to_time_t(const time_point&amp; t) <ins>noexcept</ins>;
</pre>

<pre>
<ins>static</ins> time_point from_time_t(time_t t) <ins>noexcept</ins>;
</pre>
</blockquote>

</li>

<li>
<p>Modify 30.7.7 <a href="https://wg21.link/time.clock.steady">[time.clock.steady]</a> p. 1, class <code>steady_clock</code> synopsis, as follows:</p>

<blockquote><pre>
class steady_clock {
public:
  typedef <i>unspecified</i> rep;
  typedef ratio&lt;<i>unspecified</i> , <i>unspecified</i> &gt; period;
  typedef chrono::duration&lt;rep, period&gt; duration;
  typedef chrono::time_point&lt;<i>unspecified</i>, duration&gt; time_point;
  static const bool is_monotonic is_steady = true;

  static time_point now() <ins>noexcept</ins>;
};
</pre></blockquote>

</li>

<li>
<p> Modify 30.7.8 <a href="https://wg21.link/time.clock.hires">[time.clock.hires]</a> p. 1, class <code>high_resolution_clock</code> synopsis, as follows:</p>

<blockquote><pre>
class high_resolution_clock {
public:
  typedef <i>unspecified</i> rep;
  typedef ratio&lt;<i>unspecified</i> , <i>unspecified</i> &gt; period;
  typedef chrono::duration&lt;rep, period&gt; duration;
  typedef chrono::time_point&lt;<i>unspecified</i>, duration&gt; time_point;
  static const bool is_monotonic is_steady = <i>unspecified</i>;

  static time_point now() <ins>noexcept</ins>;
};
</pre></blockquote>

</li>

<li><p>Add a new paragraph at the end of 32.2.4 <a href="https://wg21.link/thread.req.timing">[thread.req.timing]</a>:</p>

<blockquote><p>
6 The resolution of timing provided by an implementation depends on both operating system and hardware.
The finest resolution provided by an implementation is called the <i>native resolution</i>.
</p></blockquote>

<blockquote><p>
<ins>? Implementation-provided clocks that are used for these functions shall meet the <code>TrivialClock</code>
requirements (30.3 <a href="https://wg21.link/time.clock.req">[time.clock.req]</a>).</ins>
</p></blockquote>
</li>

<li>
<p>Edit the synopsis of 32.4.5 <a href="https://wg21.link/thread.thread.this">[thread.thread.this]</a> before p. 1. 
<i>[Note: this duplicates edits also in D/N3267]</i>:
</p>

<blockquote><pre>
template &lt;class Clock, class Duration&gt;
void sleep_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) <del>noexcept</del>;
template &lt;class Rep, class Period&gt;
void sleep_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) <del>noexcept</del>;
</pre></blockquote>
</li>

<li>
<p>Modify the prototype specifications in 32.4.5 <a href="https://wg21.link/thread.thread.this">[thread.thread.this]</a> before p. 4 and p. 6 and
re-add a <i>Throws</i> element following the <i>Synchronization</i> elements at p. 5 and p. 7:</p>

<blockquote><pre>
template &lt;class Clock, class Duration&gt;
void sleep_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) <del>noexcept</del>;
</pre><blockquote><p>
4 - [...]
<p/>
5 - <i>Synchronization</i>: None.
<p/>
<ins>? - <i>Throws</i>: Nothing if <code>Clock</code> satisfies the <code>TrivialClock</code> requirements (30.3 <a href="https://wg21.link/time.clock.req">[time.clock.req]</a>) and
operations of <code>Duration</code> do not throw exceptions.
[<i>Note</i>: Instantiations of time point types and clocks supplied by the implementation as specified in 30.7 <a href="https://wg21.link/time.clock">[time.clock]</a> 
do not throw exceptions. &mdash; <i>end note</i>]</ins>
</p>
</blockquote></blockquote>

<blockquote><pre>
template &lt;class Rep, class Period&gt;
void sleep_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) <del>noexcept</del>;
</pre><blockquote><p>
6 [...]
<p/>
7 <i>Synchronization</i>: None.
<p/>
<ins>? <i>Throws</i>: Nothing if operations of <code>chrono::duration&lt;Rep, Period&gt;</code> do not throw exceptions.
[<i>Note</i>: Instantiations of duration types supplied by the implementation as specified in 30.7 <a href="https://wg21.link/time.clock">[time.clock]</a> 
do not throw exceptions. &mdash; <i>end note</i>]</ins>
</p>
</blockquote></blockquote>
</li>

<li><p>Fix a minor incorrectness in p. 5: Duration types need to compare against <code>duration&lt;&gt;::zero()</code>,
not <code>0</code>:</p>

<blockquote><p>
3 The expression <code>m.try_lock_for(rel_time)</code> shall be well-formed and have the following semantics:
<p/>
[...]
<p/>
5 <i>Effects</i>: The function attempts to obtain ownership of the mutex within the relative timeout (30.2.4)
specified by <code>rel_time</code>. If the time specified by <code>rel_time</code> is less than or equal to <del><code>0</code></del><ins><code>rel_time.zero()</code></ins>, 
the function attempts to obtain ownership without blocking (as if by calling <code>try_lock()</code>). The function shall return
within the timeout specified by <code>rel_time</code> only if it has obtained ownership of the mutex object.
[ <i>Note</i>: As with <code>try_lock()</code>, there is no guarantee that ownership will be obtained if the lock is
available, but implementations are expected to make a strong effort to do so. &mdash; <i>end note</i> ]
</p>
</blockquote>
</li>

<li><p>Modify the class <code>timed_mutex</code> synopsis in 32.6.4.3.2 <a href="https://wg21.link/thread.timedmutex.class">[thread.timedmutex.class]</a> as indicated:
<i>[Note: this duplicates edits also in D/N3267]</i>:
</p>

<blockquote><pre>
class timed_mutex {
public:
  [...]
  template &lt;class Rep, class Period&gt;
    bool try_lock_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) <del>noexcept</del>;
  template &lt;class Clock, class Duration&gt;
    bool try_lock_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) <del>noexcept</del>;
  [...]
};
</pre></blockquote>
</li>

<li><p>Modify the class <code>recursive_timed_mutex</code> synopsis in 32.6.4.3.3 <a href="https://wg21.link/thread.timedmutex.recursive">[thread.timedmutex.recursive]</a> as indicated:
<i>[Note: this duplicates edits also in D/N3267]</i>:
</p>

<blockquote><pre>
class recursive_timed_mutex {
public:
  [...]
  template &lt;class Rep, class Period&gt;
    bool try_lock_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) <del>noexcept</del>;
  template &lt;class Clock, class Duration&gt;
    bool try_lock_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) <del>noexcept</del>;
  [...]
};
</pre></blockquote>
</li>

<li><p>Modify the class template <code>unique_lock</code> synopsis in 32.6.5.4 <a href="https://wg21.link/thread.lock.unique">[thread.lock.unique]</a> as indicated.
<i>[Note: this duplicates edits also in D/N3267]</i>:
</p>

<blockquote><pre>
template &lt;class Mutex&gt;
class unique_lock {
public:
  [...]
  template &lt;class Clock, class Duration&gt;
    unique_lock(mutex_type&amp; m, const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) <del>noexcept</del>;
  template &lt;class Rep, class Period&gt;
    unique_lock(mutex_type&amp; m, const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) <del>noexcept</del>;
  [...]
};
</pre></blockquote>
</li>

<li><p>Modify the constructor prototypes in 32.6.5.4.2 <a href="https://wg21.link/thread.lock.unique.cons">[thread.lock.unique.cons]</a> before p. 14 and p. 17 
<i>[Note: this duplicates edits also in D&#47;N3267]</i>:
</p>

<blockquote><pre>
template &lt;class Clock, class Duration&gt;
  unique_lock(mutex_type&amp; m, const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) <del>noexcept</del>;
</pre></blockquote>

<blockquote><pre>
template &lt;class Rep, class Period&gt;
  unique_lock(mutex_type&amp; m, const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) <del>noexcept</del>;
</pre></blockquote>
</li>


</ol>






</body>
</html>
