<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 604: [dec.tr] Storing a reference to a facet unsafe.</title>
<meta property="og:title" content="Issue 604: [dec.tr] Storing a reference to a facet unsafe.">
<meta property="og:description" content="C++ library issue. Status: TRDec">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue604.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#TRDec">TRDec</a> status.</em></p>
<h3 id="604"><a href="lwg-defects.html#604">604</a>. [dec.tr] Storing a reference to a facet unsafe.</h3>
<p><b>Section:</b> 3 [dec.tr::trdec.types] <b>Status:</b> <a href="lwg-active.html#TRDec">TRDec</a>
 <b>Submitter:</b> Martin Sebor <b>Opened:</b> 2006-05-28 <b>Last modified:</b> 2016-01-31</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#dec.tr::trdec.types">issues</a> in [dec.tr::trdec.types].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#TRDec">TRDec</a> status.</p>
<p><b>Discussion:</b></p>
<p>
In c++std-lib-17197, Martin writes:
</p>
<blockquote><p>
The extended_num_get and extended_num_put facets are designed
to store a reference to a num_get or num_put facet which the
extended facets delegate the parsing and formatting of types
other than decimal. One form of the extended facet's ctor (the
default ctor and the size_t overload) obtains the reference
from the global C++ locale while the other form takes this
reference as an argument.
</p></blockquote>
<blockquote><p>
The problem with storing a reference to a facet in another
object (as opposed to storing the locale object in which the
facet is installed) is that doing so bypasses the reference
counting mechanism designed to prevent a facet that is still
being referenced (i.e., one that is still installed in some
locale) from being destroyed when another locale that contains
it is destroyed. Separating a facet reference from the locale
it comes from van make it cumbersome (and in some cases might
even make it impossible) for programs to prevent invalidating
the reference. (The danger of this design is highlighted in
the paper.)
</p></blockquote>
<blockquote><p>
This problem could be easily avoided by having the extended
facets store a copy of the locale from which they would extract
the base facet either at construction time or when needed. To
make it possible, the forms of ctors of the extended facets that
take a reference to the base facet would need to be changed to
take a locale argument instead.
</p></blockquote>


<p id="res-604"><b>Proposed resolution:</b></p>
<p>
1. Change the <code>extended_num_get</code> synopsis in 3.10.2 as follows:
</p>
<pre>
            extended_num_get(const <del>std::num_get&lt;charT, InputIterator></del> <ins>std::locale</ins> &amp; <i>b</i>, size_t <i>refs</i> = 0);

            /* ... */

            <del>// <i>const std::num_get&lt;charT, InputIterator> &amp; <b>base</b></i>;        <i><b>exposition only</b></i></del>
            <ins>// <i>std::locale <b>baseloc</b></i>;                                    <i><b>exposition only</b></i></ins>
</pre>
<p>
2. Change the description of the above constructor in 3.10.2.1:
</p>
<pre>
            extended_num_get(const <del>std::num_get&lt;charT, InputIterator></del> <ins>std::locale</ins> &amp; <i>b</i>, size_t <i>refs</i> = 0);

</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an <code>extended_num_get</code> facet as if by:
</p>
<pre>
       extended_num_get(const <del>std::num_get&lt;charT, InputIterator></del> <ins>std::locale</ins> &amp; <i>b</i>, size_t <i>refs</i> = 0)
                : facet(<i>refs</i>), <i>base<ins>loc</ins></i>(<i>b</i>)
                { /* ... */ }

</pre>
<p>
<del><b>Notes:</b> Care must be taken by the implementation to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_get</code> facet.</del>
</p>
</blockquote>
<p>
3. Change the <b>Returns:</b> clause for <code>do_get(iter_type, iter_type, ios_base &amp;, ios_base::iostate &amp;, bool &amp;) const</code>, <i>et al</i> to
</p>
<blockquote><p>
<b>Returns:</b> <code><del><i>base</i></del> <ins>std::use_facet&lt;std::num_get&lt;charT, InputIterator> >(<i>baseloc</i>)</ins>.get(<i>in</i>, <i>end</i>, <i>str</i>, <i>err</i>, <i>val</i>)</code>. 
</p></blockquote>
<p>
4. Change the <code>extended_num_put</code> synopsis in 3.10.3 as follows:
</p>
<pre>
            extended_num_put(const <del>std::num_put&lt;charT, OutputIterator></del> <ins>std::locale</ins> &amp; <i>b</i>, size_t <i>refs</i> = 0);

            /* ... */

            <del>// <i>const std::num_put&lt;charT, OutputIterator> &amp; <b>base</b></i>;       <i><b>exposition only</b></i></del>
            <ins>// <i>std::locale <b>baseloc</b></i>;                                    <i><b>exposition only</b></i></ins>
</pre>
<p>
5. Change the description of the above constructor in 3.10.3.1:
</p>
<pre>
            extended_num_put(const <del>std::num_put&lt;charT, OutputIterator></del> <ins>std::locale</ins> &amp; <i>b</i>, size_t <i>refs</i> = 0);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an <code>extended_num_put</code> facet as if by:
</p>
<pre>
       extended_num_put(const <del>std::num_put&lt;charT, OutputIterator></del> <ins>std::locale</ins> &amp; <i>b</i>, size_t <i>refs</i> = 0)
                : facet(<i>refs</i>), <i>base<ins>loc</ins></i>(<i>b</i>)
                { /* ... */ }

</pre>
<p>
<del><b>Notes:</b> Care must be taken by the implementation to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_put</code> facet.</del>
</p>
</blockquote>
<p>
6. Change the <b>Returns:</b> clause for <code>do_put(iter_type, ios_base &amp;, char_type, bool &amp;) const</code>, <i>et al</i> to
</p>
<blockquote><p>
<b>Returns:</b> <code><del><i>base</i></del> <ins>std::use_facet&lt;std::num_put&lt;charT, OutputIterator> >(<i>baseloc</i>)</ins>.put(<i>s</i>, <i>f</i>, <i>fill</i>, <i>val</i>)</code>. 
</p></blockquote>

<p><i>[
Redmond:  We would prefer to rename "extended" to "decimal".
]</i></p>






</body>
</html>
