<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2360: reverse_iterator::operator*() is unimplementable</title>
<meta property="og:title" content="Issue 2360: reverse_iterator::operator*() is unimplementable">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2360.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++14">C++14</a> status.</em></p>
<h3 id="2360"><a href="lwg-defects.html#2360">2360</a>. <code>reverse_iterator::operator*()</code> is unimplementable</h3>
<p><b>Section:</b> 24.5.1.2 <a href="https://wg21.link/reverse.iterator">[reverse.iterator]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> Stephan T. Lavavej <b>Opened:</b> 2014-02-07 <b>Last modified:</b> 2014-02-27</p>
<p><b>Priority: </b>1
</p>
<p><b>View all other</b> <a href="lwg-index.html#reverse.iterator">issues</a> in [reverse.iterator].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Previously, C++03 24.4.1.3.3 [lib.reverse.iter.op.star] required:
</p>
<blockquote>
<pre>
reference operator*() const;
</pre>
<blockquote>
<p>
<i>Effects</i>: 
</p>
<blockquote><pre>
Iterator tmp = current;
return *--tmp;
</pre></blockquote>
</blockquote></blockquote>
<p>
Now, N3797 24.5.1.1 [reverse.iterator] depicts:
</p>
<blockquote><pre>
private:
  Iterator deref_tmp; // exposition only
};
</pre></blockquote>
<p>
And 24.5.1.3.4 [reverse.iter.op.star] requires:
</p>
<blockquote>
<pre>
reference operator*() const;
</pre>
<blockquote>
<p>
<i>Effects</i>: 
</p>
<blockquote><pre>
deref_tmp = current;
--deref_tmp;
return *deref_tmp;
</pre></blockquote>
<p>
[<i>Note</i>: This operation must use an auxiliary member variable rather than a temporary variable to avoid 
returning a reference that persists beyond the lifetime of its associated iterator. (See 24.2.) &mdash; <i>end note</i>]
</p>
</blockquote></blockquote>

<p>
As written, this won't compile, because <code>operator*()</code> is <code>const</code> yet it's modifying (via assignment and decrement) 
the <code>deref_tmp</code> data member. So what happens if you say "<code>mutable Iterator deref_tmp;</code>"?
<p/>
DANGER: WARP CORE BREACH IMMINENT.
<p/>
The Standard requires <code>const</code> member functions to be callable from multiple threads simultaneously. This is 
16.4.6.10 <a href="https://wg21.link/res.on.data.races">[res.on.data.races]</a>/3: "A C++ standard library function shall not directly or indirectly modify objects (1.10) 
accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's 
non-const arguments, including <code>this</code>."
<p/>
Multiple threads simultaneously modifying <code>deref_tmp</code> will trigger data races, so both <code>mutable</code> and some form of 
synchronization (e.g. <code>mutex</code> or <code>atomic</code>) are actually necessary!
<p/>
Here's what implementations currently do: Dinkumware/VC follows C++03 and doesn't use <code>deref_tmp</code> (attempting to 
implement it is what led me to file this issue). According to Jonathan Wakely, libstdc++ also follows C++03 (see 
<a href="http://gcc.gnu.org/PR51823">PR51823</a> which is suspended until LWG <a href="lwg-closed.html#2204" title="reverse_iterator should not require a second copy of the base iterator (Status: NAD)">2204</a><sup><a href="https://cplusplus.github.io/LWG/issue2204" title="Latest snapshot">(i)</a></sup> is resolved). According to 
Marshall Clow, libc++ uses <code>deref_tmp</code> with <code>mutable</code> but without synchronization, so it can trigger data races.
<p/>
This <code>deref_tmp</code> Standardese was added by LWG <a href="lwg-defects.html#198" title="Validity of pointers and references unspecified after iterator destruction (Status: CD1)">198</a><sup><a href="https://cplusplus.github.io/LWG/issue198" title="Latest snapshot">(i)</a></sup> "Validity of pointers and references unspecified after 
iterator destruction" and is present in Working Papers going back to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1638.pdf">N1638</a> 
on April 11, 2004, long before C++ recognized the existence of multithreading and developed the "<code>const</code> means simultaneously 
readable" convention.
<p/>
A related issue is LWG <a href="lwg-defects.html#1052" title="reverse_iterator::operator-&gt; should also support smart pointers (Status: Resolved)">1052</a><sup><a href="https://cplusplus.github.io/LWG/issue1052" title="Latest snapshot">(i)</a></sup> "<code>reverse_iterator::operator-&gt;</code> should also support smart pointers" which 
mentioned the need to depict <code>mutable</code> in the Standardese, but it was resolved NAD Future and no change was made.
<p/>
Finally, LWG <a href="lwg-closed.html#2204" title="reverse_iterator should not require a second copy of the base iterator (Status: NAD)">2204</a><sup><a href="https://cplusplus.github.io/LWG/issue2204" title="Latest snapshot">(i)</a></sup> "<code>reverse_iterator</code> should not require a second copy of the base iterator" talked about 
removing <code>deref_tmp</code>, but without considering multithreading.
<p/>
I argue that <code>deref_tmp</code> must be removed. Its existence has highly undesirable consequences: either no synchronization 
is used, violating the Standard's usual multithreading guarantees, or synchronization is used, adding further costs for all 
users that benefit almost no iterators.
<p/>
<code>deref_tmp</code> is attempting to handle iterators that return references to things "inside themselves", which I usually call 
"stashing iterators" (as they have a secret stash). Note that these are very unusual, and are different from proxy iterators like 
<code>vector&lt;bool&gt;::iterator</code>.  While <code>vector&lt;bool&gt;::iterator</code>'s <code>operator*()</code> does not return a true 
reference, it refers to a bit that is unrelated to the iterator's lifetime.
</p>

<p><i>[2014-02-14 Issaquah meeting: Move to Immediate]</i></p>

<p>
Strike superfluous note to avoid potential confusion, and move to Immediate.
</p>



<p id="res-2360"><b>Proposed resolution:</b></p>
<p>This wording is relative to N3797.</p>

<ol>
<li><p>Change class template <code>reverse_iterator</code> synopsis, 24.5.1.2 <a href="https://wg21.link/reverse.iterator">[reverse.iterator]</a>, as indicated:</p>

<blockquote><pre>
[&hellip;]
protected:
  Iterator current;
<del>private:
  Iterator deref_tmp; // exposition only</del>
};
</pre></blockquote>
</li>

<li><p>Change  [reverse.iter.op.star] as indicated:</p>

<blockquote><pre>
reference operator*() const;
</pre>
<blockquote>
<p>
-1- <i>Effects</i>:
</p>
<blockquote><pre>
<del>deref_tmp = current;
--deref_tmp;
return *deref_tmp;</del>
<ins>Iterator tmp = current;
return *--tmp;</ins>
</pre></blockquote>
<p>
<del>-2- [<i>Note</i>: This operation must use an auxiliary member variable rather than a temporary variable to
avoid returning a reference that persists beyond the lifetime of its associated iterator. (See 24.2.) &mdash; <i>end note</i>]</del>
</p>
</blockquote></blockquote>
</li>
</ol>






</body>
</html>
