gcc/libstdc++-v3/docs/html/ext/lwg-active.html
Phil Edwards 77cd227ec3 howto.html: Add anchor name.
2001-09-25  Phil Edwards  <pme@gcc.gnu.org>

	* docs/html/20_util/howto.html:  Add anchor name.
	* docs/html/23_containers/howto.html:  Line wrapping, another link.
	* docs/html/25_algorithms/howto.html:  Another note.

	* docs/html/ext/howto.html:  Link to SGI extensions.  List DRs and
	link to them...
	* docs/html/ext/lwg-active.html:  ...in this new file (from R19),
	* docs/html/ext/lwg-defects.html:  and this new file (from R19).
	* docs/html/ext/sgiexts.html:  New file.  Mention SGI extensions
	carried over to libstdc++-v3.
	* docs/html/faq/index.html:  Link to SGI extensions.  Mention the
	"missing .." pseudobug.
	* docs/html/faq/index.txt:  Regenerate.

	* include/bits/ios_base.h:  DR-related comment cleanup.
	* include/bits/istream.tcc:  Likewise.
	* include/bits/locale_facets.h:  Likewise.
	* include/bits/locale_facets.tcc:  Likewise.
	* include/bits/ostream.tcc:  Likewise.
	* include/bits/std_bitset.h:  Likewise.
	* include/bits/std_iosfwd.h:  Likewise.
	* include/bits/std_istream.h:  Likewise.
	* include/bits/std_ostream.h:  Likewise.
	* include/bits/std_streambuf.h:  Likewise.
	* include/bits/stl_pair.h:  Likewise.
	* include/bits/streambuf_iterator.h:  Likewise.

	* include/bits/std_map.h:  Remove unused header inclusion guard
	_CPP_BITS_STL_TREE_H from around bits/stl_tree.h.
	* include/bits/std_set.h:  Likewise.

	* include/bits/stl_function.h:  Doxygen markup.
	* docs/doxygen/doxygroups.cc:  New file, specifying module grouping.
	* libsupc++/typeinfo:  Doxygen markup tweak.

From-SVN: r45816
2001-09-25 23:51:17 +00:00

6443 lines
274 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head><title>C++ Standard Library Active Issues List</title></head>
<body bgcolor="#ffffff" text="#000000">
<table>
<tr>
<td align="left">Doc. no.</td>
<td align="left">J16/01-0031 = WG21 N1317</td>
</tr>
<tr>
<td align="left">Date:</td>
<td align="left">11 Sep 2001</td>
</tr>
<tr>
<td align="left">Project:</td>
<td align="left">Programming Language C++</td>
</tr>
<tr>
<td align="left">Reply to:</td>
<td align="left">Matt Austern &lt;austern@research.att.com&gt;</td>
</tr>
</table>
<h1>C++ Standard Library Active Issues List (Revision 19)</h1>
<p>Reference ISO/IEC IS 14882:1998(E)</p>
<p>Also see:</p>
<ul>
<li>
<a href="lwg-toc.html">Table of Contents</a> for all library issues.</li>
<li>
<a href="lwg-index.html">Index by Section</a> for all library issues.</li>
<li>
<a href="lwg-status.html">Index by Status</a> for all library issues.</li>
<li><a href="lwg-defects.html">Library Defect Reports List</a></li>
<li><a href="lwg-closed.html">Library Closed Issues List</a></li>
</ul>
<p>The purpose of this document is to record the status of issues
which have come before the Library Working Group (LWG) of the ANSI
(J16) and ISO (WG21) C++ Standards Committee. Issues represent
potential defects in the ISO/IEC IS 14882:1998(E) document. Issues
are not to be used to request new features or other extensions. </p>
<p>This document contains only library issues which are actively being
considered by the Library Working Group. That is, issues which have a
status of <a href="lwg-active.html#New">New</a>, <a href="lwg-active.html#Open">Open</a>,
<a href="lwg-active.html#Ready">Ready</a>, and <a href="lwg-active.html#Review">Review</a>. See
<a href="lwg-defects.html">Library Defect Reports List</a> for issues considered defects and
<a href="lwg-closed.html">Library Closed Issues List</a> for issues considered closed.</p>
<p>The issues in these lists are not necessarily formal ISO Defect
Reports (DR's). While some issues will eventually be elevated to
official Defect Report status, other issues will be disposed of in
other ways. See <a href="#Status">Issue Status</a>.</p>
<p>This document is in an experimental format designed for both
viewing via a world-wide web browser and hard-copy printing. It
is available as an HTML file for browsing or PDF file for
printing.</p>
<p>Prior to Revision 14, library issues lists existed in two slightly
different versions; a Committee Version and a Public
Version. Beginning with Revision 14 the two versions were combined
into a single version.</p>
<p>This document includes <i>[bracketed italicized notes]</i> as a
reminder to the LWG of current progress on issues. Such notes are
strictly unofficial and should be read with caution as they may be
incomplete or incorrect. Be aware that LWG support for a particular
resolution can quickly change if new viewpoints or killer examples are
presented in subsequent discussions.</p>
<p>For the most current official version of this document see
<a href="http://www.dkuug.dk/jtc1/sc22/wg21">http://www.dkuug.dk/jtc1/sc22/wg21</a>.
Requests for further information about this document should include
the document number above, reference ISO/IEC 14882:1998(E), and be
submitted to Information Technology Industry Council (ITI), 1250 Eye
Street NW, Washington, DC 20005.</p>
<p>Public information as to how to obtain a copy of the C++ Standard,
join the standards committee, submit an issue, or comment on an issue
can be found in the C++ FAQ at <a href="http://www.research.att.com/~austern/csc/faq.html">http://www.research.att.com/~austern/csc/faq.html</a>.
Public discussion of C++ Standard related issues occurs on <a href="news:comp.std.c++">news:comp.std.c++</a>.
</p>
<p>For committee members, files available on the committee's private
web site include the HTML version of the Standard itself. HTML
hyperlinks from this issues list to those files will only work for
committee members who have downloaded them into the same disk
directory as the issues list files. </p>
<h2>Revision History</h2>
<ul>
<li>R19:
Pre-Redmond mailing. Added new issues
<a href="lwg-active.html#323">323</a>-<a href="lwg-active.html#335">335</a>.
</li>
<li>R18:
Post-Copenhagen mailing; reflects actions taken in Copenhagen.
Added new issues <a href="lwg-active.html#312">312</a>-<a href="lwg-active.html#317">317</a>, and discussed
new issues <a href="lwg-active.html#271">271</a>-<a href="lwg-closed.html#314">314</a>.
Changed status of issues
<a href="lwg-defects.html#103">103</a> <a href="lwg-defects.html#118">118</a> <a href="lwg-defects.html#136">136</a> <a href="lwg-defects.html#153">153</a>
<a href="lwg-defects.html#165">165</a> <a href="lwg-defects.html#171">171</a> <a href="lwg-defects.html#183">183</a> <a href="lwg-defects.html#184">184</a>
<a href="lwg-defects.html#185">185</a> <a href="lwg-defects.html#186">186</a> <a href="lwg-defects.html#214">214</a> <a href="lwg-defects.html#221">221</a>
<a href="lwg-defects.html#234">234</a> <a href="lwg-defects.html#237">237</a> <a href="lwg-defects.html#243">243</a> <a href="lwg-defects.html#248">248</a>
<a href="lwg-defects.html#251">251</a> <a href="lwg-defects.html#252">252</a> <a href="lwg-defects.html#256">256</a> <a href="lwg-defects.html#260">260</a>
<a href="lwg-defects.html#261">261</a> <a href="lwg-defects.html#262">262</a> <a href="lwg-defects.html#263">263</a> <a href="lwg-defects.html#265">265</a>
<a href="lwg-defects.html#268">268</a>
to DR.
Changed status of issues
<a href="lwg-active.html#49">49</a> <a href="lwg-active.html#109">109</a> <a href="lwg-active.html#117">117</a> <a href="lwg-active.html#182">182</a>
<a href="lwg-active.html#228">228</a> <a href="lwg-active.html#230">230</a> <a href="lwg-active.html#232">232</a> <a href="lwg-active.html#235">235</a>
<a href="lwg-active.html#238">238</a> <a href="lwg-active.html#241">241</a> <a href="lwg-active.html#242">242</a> <a href="lwg-active.html#250">250</a>
<a href="lwg-active.html#259">259</a> <a href="lwg-active.html#264">264</a> <a href="lwg-active.html#266">266</a> <a href="lwg-active.html#267">267</a>
<a href="lwg-active.html#271">271</a> <a href="lwg-active.html#272">272</a> <a href="lwg-active.html#273">273</a> <a href="lwg-active.html#275">275</a>
<a href="lwg-active.html#281">281</a> <a href="lwg-active.html#284">284</a> <a href="lwg-active.html#285">285</a> <a href="lwg-active.html#286">286</a>
<a href="lwg-active.html#288">288</a> <a href="lwg-active.html#292">292</a> <a href="lwg-active.html#295">295</a> <a href="lwg-active.html#297">297</a>
<a href="lwg-active.html#298">298</a> <a href="lwg-active.html#301">301</a> <a href="lwg-active.html#303">303</a> <a href="lwg-active.html#306">306</a>
<a href="lwg-active.html#307">307</a> <a href="lwg-active.html#308">308</a> <a href="lwg-active.html#312">312</a>
to Ready.
Closed issues
<a href="lwg-closed.html#111">111</a> <a href="lwg-closed.html#277">277</a> <a href="lwg-closed.html#279">279</a> <a href="lwg-closed.html#287">287</a>
<a href="lwg-closed.html#289">289</a> <a href="lwg-closed.html#293">293</a> <a href="lwg-closed.html#302">302</a> <a href="lwg-closed.html#313">313</a>
<a href="lwg-closed.html#314">314</a>
as NAD.
</li>
<li>R17:
Pre-Copenhagen mailing. Converted issues list to XML. Added proposed
resolutions for issues <a href="lwg-active.html#49">49</a>, <a href="lwg-active.html#76">76</a>, <a href="lwg-active.html#91">91</a>, <a href="lwg-active.html#235">235</a>, <a href="lwg-active.html#250">250</a>, <a href="lwg-active.html#267">267</a>.
Added new issues <a href="lwg-active.html#278">278</a>-<a href="lwg-active.html#311">311</a>.
</li>
<li>R16:
post-Toronto mailing; reflects actions taken in Toronto. Added new
issues <a href="lwg-defects.html#265">265</a>-<a href="lwg-closed.html#277">277</a>. Changed status of issues
<a href="lwg-defects.html#3">3</a>, <a href="lwg-defects.html#8">8</a>, <a href="lwg-defects.html#9">9</a>, <a href="lwg-defects.html#19">19</a>,
<a href="lwg-defects.html#26">26</a>, <a href="lwg-defects.html#31">31</a>, <a href="lwg-defects.html#61">61</a>,
<a href="lwg-defects.html#63">63</a>, <a href="lwg-defects.html#86">86</a>, <a href="lwg-defects.html#108">108</a>,
<a href="lwg-defects.html#112">112</a>, <a href="lwg-defects.html#114">114</a>, <a href="lwg-defects.html#115">115</a>,
<a href="lwg-defects.html#122">122</a>, <a href="lwg-defects.html#127">127</a>, <a href="lwg-defects.html#129">129</a>,
<a href="lwg-defects.html#134">134</a>, <a href="lwg-defects.html#137">137</a>, <a href="lwg-defects.html#142">142</a>,
<a href="lwg-defects.html#144">144</a>, <a href="lwg-defects.html#146">146</a>, <a href="lwg-defects.html#147">147</a>,
<a href="lwg-defects.html#159">159</a>, <a href="lwg-defects.html#164">164</a>, <a href="lwg-defects.html#170">170</a>,
<a href="lwg-defects.html#181">181</a>, <a href="lwg-defects.html#199">199</a>, <a href="lwg-defects.html#208">208</a>,
<a href="lwg-defects.html#209">209</a>, <a href="lwg-defects.html#210">210</a>, <a href="lwg-defects.html#211">211</a>,
<a href="lwg-defects.html#212">212</a>, <a href="lwg-defects.html#217">217</a>, <a href="lwg-defects.html#220">220</a>,
<a href="lwg-defects.html#222">222</a>, <a href="lwg-defects.html#223">223</a>, <a href="lwg-defects.html#224">224</a>,
<a href="lwg-defects.html#227">227</a> to &quot;DR&quot;. Reopened issue <a href="lwg-active.html#23">23</a>. Reopened
issue <a href="lwg-active.html#187">187</a>. Changed issues <a href="lwg-closed.html#2">2</a> and
<a href="lwg-closed.html#4">4</a> to NAD. Fixed a typo in issue <a href="lwg-defects.html#17">17</a>. Fixed
issue <a href="lwg-defects.html#70">70</a>: signature should be changed both places it
appears. Fixed issue <a href="lwg-defects.html#160">160</a>: previous version didn't fix
the bug in enough places.
</li>
<li>R15:
pre-Toronto mailing. Added issues
<a href="lwg-active.html#233">233</a>-<a href="lwg-active.html#264">264</a>. Some small HTML formatting
changes so that we pass Weblint tests.
</li>
<li>R14:
post-Tokyo II mailing; reflects committee actions taken in
Tokyo. Added issues <a href="lwg-active.html#228">228</a> to <a href="lwg-active.html#232">232</a>. (00-0019R1/N1242)
</li>
<li>R13:
pre-Tokyo II updated: Added issues <a href="lwg-defects.html#212">212</a> to <a href="lwg-defects.html#227">227</a>.
</li>
<li>R12:
pre-Tokyo II mailing: Added issues <a href="lwg-defects.html#199">199</a> to
<a href="lwg-defects.html#211">211</a>. Added &quot;and paragraph 5&quot; to the proposed resolution
of issue <a href="lwg-defects.html#29">29</a>. Add further rationale to issue
<a href="lwg-closed.html#178">178</a>.
</li>
<li>R11:
post-Kona mailing: Updated to reflect LWG and full committee actions
in Kona (99-0048/N1224). Note changed resolution of issues
<a href="lwg-closed.html#4">4</a> and <a href="lwg-defects.html#38">38</a>. Added issues <a href="lwg-closed.html#196">196</a>
to <a href="lwg-active.html#198">198</a>. Closed issues list split into &quot;defects&quot; and
&quot;closed&quot; documents. Changed the proposed resolution of issue
<a href="lwg-closed.html#4">4</a> to NAD, and changed the wording of proposed resolution
of issue <a href="lwg-defects.html#38">38</a>.
</li>
<li>R10:
pre-Kona updated. Added proposed resolutions <a href="lwg-defects.html#83">83</a>,
<a href="lwg-defects.html#86">86</a>, <a href="lwg-active.html#91">91</a>, <a href="lwg-active.html#92">92</a>,
<a href="lwg-active.html#109">109</a>. Added issues <a href="lwg-closed.html#190">190</a> to
<a href="lwg-defects.html#195">195</a>. (99-0033/D1209, 14 Oct 99)
</li>
<li>R9:
pre-Kona mailing. Added issues <a href="lwg-closed.html#140">140</a> to
<a href="lwg-defects.html#189">189</a>. Issues list split into separate &quot;active&quot; and
&quot;closed&quot; documents. (99-0030/N1206, 25 Aug 99)
</li>
<li>R8:
post-Dublin mailing. Updated to reflect LWG and full committee actions
in Dublin. (99-0016/N1193, 21 Apr 99)
</li>
<li>R7:
pre-Dublin updated: Added issues <a href="lwg-closed.html#130">130</a>, <a href="lwg-closed.html#131">131</a>,
<a href="lwg-defects.html#132">132</a>, <a href="lwg-defects.html#133">133</a>, <a href="lwg-defects.html#134">134</a>,
<a href="lwg-closed.html#135">135</a>, <a href="lwg-defects.html#136">136</a>, <a href="lwg-defects.html#137">137</a>,
<a href="lwg-closed.html#138">138</a>, <a href="lwg-defects.html#139">139</a> (31 Mar 99)
</li>
<li>R6:
pre-Dublin mailing. Added issues <a href="lwg-defects.html#127">127</a>, <a href="lwg-closed.html#128">128</a>,
and <a href="lwg-defects.html#129">129</a>. (99-0007/N1194, 22 Feb 99)
</li>
<li>R5:
update issues <a href="lwg-defects.html#103">103</a>, <a href="lwg-defects.html#112">112</a>; added issues
<a href="lwg-defects.html#114">114</a> to <a href="lwg-defects.html#126">126</a>. Format revisions to prepare
for making list public. (30 Dec 98)
</li>
<li>R4:
post-Santa Cruz II updated: Issues <a href="lwg-defects.html#110">110</a>,
<a href="lwg-closed.html#111">111</a>, <a href="lwg-defects.html#112">112</a>, <a href="lwg-closed.html#113">113</a> added, several
issues corrected. (22 Oct 98)
</li>
<li>R3:
post-Santa Cruz II: Issues <a href="lwg-closed.html#94">94</a> to <a href="lwg-active.html#109">109</a>
added, many issues updated to reflect LWG consensus (12 Oct 98)
</li>
<li>R2:
pre-Santa Cruz II: Issues <a href="lwg-closed.html#73">73</a> to <a href="lwg-closed.html#93">93</a> added,
issue <a href="lwg-defects.html#17">17</a> updated. (29 Sep 98)
</li>
<li>R1:
Correction to issue <a href="lwg-defects.html#55">55</a> resolution, <a href="lwg-defects.html#60">60</a> code
format, <a href="lwg-defects.html#64">64</a> title. (17 Sep 98)
</li>
</ul>
<h2>
<a name="Status"></a>Issue Status</h2>
<p>
<b><a name="New">New</a></b> - The issue has not yet been
reviewed by the LWG. Any <b>Proposed Resolution</b> is purely a
suggestion from the issue submitter, and should not be construed as
the view of LWG.</p>
<p>
<b><a name="Open">Open</a></b> - The LWG has discussed the issue
but is not yet ready to move the issue forward. There are several
possible reasons for open status:</p>
<ul>
<li>Consensus may have not yet have been reached as to how to deal
with the issue.</li>
<li>Informal consensus may have been reached, but the LWG awaits
exact <b>Proposed Resolution</b> wording for review.</li>
<li>The LWG wishes to consult additional technical experts before
proceeding.</li>
<li>The issue may require further study.</li>
</ul>
<p>A <b>Proposed Resolution</b> for an open issue is still not be
construed as the view of LWG. Comments on the current state of
discussions are often given at the end of open issues in an italic
font. Such comments are for information only and should not be given
undue importance.</p>
<p>
<b><a name="Dup">Dup</a></b> - The LWG has reached consensus that
the issue is a duplicate of another issue, and will not be further
dealt with. A <b>Rationale</b> identities the duplicated issue's
issue number. </p>
<p>
<b><a name="NAD">NAD</a></b> - The LWG has reached consensus that
the issue is not a defect in the Standard, and the issue is ready to
forward to the full committee as a proposed record of response. A
<b>Rationale</b> discusses the LWG's reasoning.</p>
<p>
<b><a name="Review">Review</a></b> - Exact wording of a
<b>Proposed Resolution</b> is now available for review on an issue
for which the LWG previously reached informal consensus.</p>
<p>
<b><a name="Ready">Ready</a></b> - The LWG has reached consensus
that the issue is a defect in the Standard, the <b>Proposed
Resolution</b> is correct, and the issue is ready to forward to the
full committee for further action as a Defect Report (DR).</p>
<p>
<b><a name="DR">DR</a></b> - (Defect Report) - The full J16
committee has voted to forward the issue to the Project Editor to be
processed as a Potential Defect Report. The Project Editor reviews
the issue, and then forwards it to the WG21 Convenor, who returns it
to the full committee for final disposition. This issues list
accords the status of DR to all these Defect Reports regardless of
where they are in that process.</p>
<p>
<b><a name="TC">TC</a></b> - (Technical Corrigenda) - The full
WG21 committee has voted to accept the Defect Report's Proposed
Resolution as a Technical Corrigenda. Action on this issue is thus
complete and no further action is possible under ISO rules.</p>
<p>
<b><a name="RR">RR</a></b> - (Record of Response) - The full WG21
committee has determined that this issue is not a defect in the
Standard. Action on this issue is thus complete and no further
action is possible under ISO rules.</p>
<p>
<b><a name="Future">Future</a></b> - In addition to the regular
status, the LWG believes that this issue should be revisited at the
next revision of the standard. It is usually paired with NAD.</p>
<p>Issues are always given the status of <a href="lwg-active.html#New">New</a> when
they first appear on the issues list. They may progress to
<a href="lwg-active.html#Open">Open</a> or <a href="lwg-active.html#Review">Review</a> while the LWG
is actively working on them. When the LWG has reached consensus on
the disposition of an issue, the status will then change to
<a href="lwg-active.html#Dup">Dup</a>, <a href="lwg-active.html#NAD">NAD</a>, or <a href="lwg-active.html#Ready">Ready</a> as appropriate. Once the full J16 committee votes to
forward Ready issues to the Project Editor, they are given the
status of Defect Report ( <a href="lwg-active.html#DR">DR</a>). These in turn may
become the basis for Technical Corrigenda (<a href="lwg-active.html#TC">TC</a>),
or are closed without action other than a Record of Response
(<a href="lwg-active.html#RR">RR</a> ). The intent of this LWG process is that
only issues which are truly defects in the Standard move to the
formal ISO DR status.
</p>
<h2>Active Issues</h2>
<hr>
<a name="23"><h3>23.&nbsp;Num_get overflow result</h3></a><p>
<b>Section:</b>&nbsp;22.2.2.1.2 <a href="lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Nathan Myers&nbsp; <b>Date:</b>&nbsp;6 Aug 1998</p>
<p>The current description of numeric input does not account for the possibility of
overflow. This is an implicit result of changing the description to rely on the definition
of scanf() (which fails to report overflow), and conflicts with the documented behavior of
traditional and current implementations. </p>
<p>Users expect, when reading a character sequence that results in a value unrepresentable
in the specified type, to have an error reported. The standard as written does not permit
this. </p>
<p><b>Further comments from Dietmar:</b></p>
<p>
I don't feel comfortable with the proposed resolution to issue 23: It
kind of simplifies the issue to much. Here is what is going on:
</p>
<p>
Currently, the behavior of numeric overflow is rather counter intuitive
and hard to trace, so I will describe it briefly:
</p>
<ul>
<li>
According to 22.2.2.1.2
paragraph 11 <tt>failbit</tt> is set if <tt>scanf()</tt> would
return an input error; otherwise a value is converted to the rules
of <tt>scanf</tt>.
</li>
<li>
<tt>scanf()</tt> is defined in terms of <tt>fscanf()</tt>.
</li>
<li>
<tt>fscanf()</tt> returns an input failure if during conversion no
character matching the conversion specification could be extracted
before reaching EOF. This is the only reason for <tt>fscanf()</tt>
to fail due to an input error and clearly does not apply to the case
of overflow.
</li>
<li>
Thus, the conversion is performed according to the rules of
<tt>fscanf()</tt> which basically says that <tt>strtod</tt>,
<tt>strtol()</tt>, etc. are to be used for the conversion.
</li>
<li>
The <tt>strtod()</tt>, <tt>strtol()</tt>, etc. functions consume as
many matching characters as there are and on overflow continue to
consume matching characters but also return a value identical to
the maximum (or minimum for signed types if there was a leading minus)
value of the corresponding type and set <tt>errno</tt> to <tt>ERANGE</tt>.
</li>
<li>
Thus, according to the current wording in the standard, overflows
can be detected! All what is to be done is to check <tt>errno</tt>
after reading an element and, of course, clearing <tt>errno</tt>
before trying a conversion. With the current wording, it can be
detected whether the overflow was due to a positive or negative
number for signed types.
</li>
</ul>
<p>
Now the proposed resolution results in not modifying the value passed
as last argument if an overflow is encountered but <tt>failbit</tt>
is set. Checking <tt>errno</tt> for <tt>ERANGE</tt> still allows for
detection of an overflow but not what the sign was.
</p>
<p>
Actually, my problem is not that much with the sign but this is at least
making things worse... My problem is more that it is still necessary
to check <tt>errno</tt> for the error description. Thus, I propose the
following resolution:
</p>
<p>Change paragraph 11 from</p>
<blockquote>
<p>
<b>-11-</b> <b>Stage 3:</b>
The result of stage 2 processing can be one of</p>
<ul>
<li>A sequence of <tt>char</tt>s
has been accumulated in stage 2 that is converted (according to the
rules of <tt>scanf)</tt> to a value of the type of <tt><i>val</i></tt>.
This value is stored in <tt><i>val</i></tt> and
<tt>ios_base::goodbit</tt> is stored in <tt><i>err</i></tt>.</li>
<li>The sequence of <tt>char</tt>s
accumulated in stage 2 would have caused scanf to report an input failure.
<tt>ios_base::failbit</tt> is assigned to <i>err</i>.</li>
</ul>
</blockquote>
<p>to become</p>
<blockquote>
<p>
<b>-11-</b> <b>Stage 3:</b>
The result of stage 2 processing can be one of</p>
<ul>
<li>A sequence of <tt>char</tt>s
has been accumulated in stage 2 that is converted (according to the
rules of <tt>scanf)</tt> to a value of the type of <tt><i>val</i></tt>.
This value is stored in <tt><i>val</i></tt>. If the conversion reported
an overflow error for the type of <tt><i>val</i></tt> (ie.
<tt><i>errno</i></tt> would be set to <tt>ERANGE</tt> by the used
conversion function) then <tt>ios_base::failbit</tt> is stored in
<tt><i>err</i></tt>, otherwise <tt>ios_base::goodbit</tt> is stored in
<tt><i>err</i></tt>.</li>
<li>The sequence of <tt>char</tt>s accumulated in stage 2 would have
caused scanf to report an input failure. <tt>ios_base::failbit</tt>
is assigned to <i>err</i>.</li>
</ul>
</blockquote>
<p>
With this definition, overflow can be detected easily by storing a value
different from the maximum value in <tt><i>val</i></tt> and checking whether
this value was modified in case <tt>failbit</tt> is set: If it was, there
was an overflow error, otherwise some other input error occurred (under the
conditions for the second bullet <tt><i>val</i></tt> is not changed).
</p>
<p><b>Proposed resolution:</b></p>
<p>In 22.2.2.1.2 , paragraph 11, second bullet item,
change </p>
<blockquote>
<p>The sequence of chars accumulated in stage 2 would have caused scanf to report an input
failure. </p>
</blockquote>
<p>to </p>
<blockquote>
<p>The sequence of chars accumulated in stage 2 would have caused scanf to report an input
failure, or the value of the sequence cannot be represented in the type of _val_. </p>
</blockquote>
<p><i>[post-Toronto: &quot;cannot be represented&quot; is probably wrong:
infinity can be represented on an IEC559 platform, but 0.1 cannot be
represented exactly. However, the alternate proposal may be wrong as
well. It's not clear whether overflow (and underflow?) should always
be treated as errors. This issue requires much more thought]</i></p>
<hr>
<a name="44"><h3>44.&nbsp;Iostreams use operator== on int_type values</h3></a><p>
<b>Section:</b>&nbsp;27 <a href="lib-iostreams.html#lib.input.output"> [lib.input.output]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Nathan Myers&nbsp; <b>Date:</b>&nbsp;6 Aug 1998</p>
<p>Many of the specifications for iostreams specify that character
values or their int_type equivalents are compared using operators ==
or !=, though in other places traits::eq() or traits::eq_int_type is
specified to be used throughout. This is an inconsistency; we should
change uses of == and != to use the traits members instead. </p>
<p><b>Proposed resolution:</b></p>
<p><i>[Kona: Nathan to supply proposed wording]</i></p>
<p><i>[
Tokyo: the LWG reaffirmed that this is a defect, and requires careful
review of clause 27 as the changes are context sensitive.
]</i></p>
<hr>
<a name="49"><h3>49.&nbsp;Underspecification of ios_base::sync_with_stdio</h3></a><p>
<b>Section:</b>&nbsp;27.4.2.4 <a href="lib-iostreams.html#lib.ios.members.static"> [lib.ios.members.static]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;21 Jun 1998</p>
<p>Two problems</p>
<p>(1) 27.4.2.4 doesn't say what ios_base::sync_with_stdio(f)
returns. Does it return f, or does it return the previous
synchronization state? My guess is the latter, but the standard
doesn't say so.</p>
<p>(2) 27.4.2.4 doesn't say what it means for streams to be
synchronized with stdio. Again, of course, I can make some
guesses. (And I'm unhappy about the performance implications of those
guesses, but that's another matter.)</p>
<p><b>Proposed resolution:</b></p>
<p>Change the following sentence in 27.4.2.4
returns clause from:</p>
<blockquote>
<p>
<tt>true</tt> if the standard iostream objects (27.3) are
synchronized and otherwise returns <tt>false</tt>.</p>
</blockquote>
<p>to:</p>
<blockquote>
<p>
<tt>true</tt> if the previous state of the standard iostream
objects (27.3) was synchronized and otherwise returns
<tt>false</tt>.</p>
</blockquote>
<p>Add the following immediately after 27.4.2.4 ,
paragraph 2:</p>
<blockquote>
<p>When a standard iostream object str is <i>synchronized</i> with a
standard stdio stream f, the effect of inserting a character c by</p>
<pre>
fputc(f, c);
</pre>
<p>is the same as the effect of</p>
<pre>
str.rdbuf()-&gt;sputc(c);
</pre>
<p>for any sequence of characters; the effect of extracting a
character c by</p>
<pre>
c = fgetc(f);
</pre>
<p>is the same as the effect of:</p>
<pre>
c = str.rdbuf()-&gt;sbumpc(c);
</pre>
<p>for any sequences of characters; and the effect of pushing
back a character c by</p>
<pre>
ungetc(c, f);
</pre>
<p>is the same as the effect of</p>
<pre>
str.rdbuf()-&gt;sputbackc(c);
</pre>
<p>for any sequence of characters. [<i>Footnote</i>: This implies
that operations on a standard iostream object can be mixed arbitrarily
with operations on the corresponding stdio stream. In practical
terms, synchronization usually means that a standard iostream object
and a standard stdio object share a buffer. <i>--End Footnote</i>]</p>
</blockquote>
<p><i>[pre-Copenhagen: PJP and Matt contributed the definition
of &quot;synchronization&quot;]</i></p>
<p><i>[post-Copenhagen: proposed resolution was revised slightly:
text was added in the non-normative footnote to say that operations
on the two streams can be mixed arbitrarily.]</i></p>
<hr>
<a name="76"><h3>76.&nbsp;Can a <tt>codecvt</tt> facet always convert one internal character at a time?</h3></a><p>
<b>Section:</b>&nbsp;22.2.1.5 <a href="lib-locales.html#lib.locale.codecvt"> [lib.locale.codecvt]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;25 Sep 1998</p>
<p>This issue concerns the requirements on classes derived from
<tt>codecvt</tt>, including user-defined classes. What are the
restrictions on the conversion from external characters
(e.g. <tt>char</tt>) to internal characters (e.g. <tt>wchar_t</tt>)?
Or, alternatively, what assumptions about <tt>codecvt</tt> facets can
the I/O library make? </p>
<p>The question is whether it's possible to convert from internal
characters to external characters one internal character at a time,
and whether, given a valid sequence of external characters, it's
possible to pick off internal characters one at a time. Or, to put it
differently: given a sequence of external characters and the
corresponding sequence of internal characters, does a position in the
internal sequence correspond to some position in the external
sequence? </p>
<p>To make this concrete, suppose that <tt>[first, last)</tt> is a
sequence of <i>M</i> external characters and that <tt>[ifirst,
ilast)</tt> is the corresponding sequence of <i>N</i> internal
characters, where <i>N &gt; 1</i>. That is, <tt>my_encoding.in()</tt>,
applied to <tt>[first, last)</tt>, yields <tt>[ifirst,
ilast)</tt>. Now the question: does there necessarily exist a
subsequence of external characters, <tt>[first, last_1)</tt>, such
that the corresponding sequence of internal characters is the single
character <tt>*ifirst</tt>?
</p>
<p>(What a &quot;no&quot; answer would mean is that
<tt>my_encoding</tt> translates sequences only as blocks. There's a
sequence of <i>M</i> external characters that maps to a sequence of
<i>N</i> internal characters, but that external sequence has no
subsequence that maps to <i>N-1</i> internal characters.) </p>
<p>Some of the wording in the standard, such as the description of
<tt>codecvt::do_max_length</tt> (22.2.1.5.2 ,
paragraph 11) and <tt>basic_filebuf::underflow</tt> (27.8.1.4 , paragraph 3) suggests that it must always be
possible to pick off internal characters one at a time from a sequence
of external characters. However, this is never explicitly stated one
way or the other. </p>
<p>This issue seems (and is) quite technical, but it is important if
we expect users to provide their own encoding facets. This is an area
where the standard library calls user-supplied code, so a well-defined
set of requirements for the user-supplied code is crucial. Users must
be aware of the assumptions that the library makes. This issue affects
positioning operations on <tt>basic_filebuf</tt>, unbuffered input,
and several of <tt>codecvt</tt>'s member functions. </p>
<p><b>Proposed resolution:</b></p>
<p>Add the following text as a new paragraph, following 22.2.1.5.2 paragraph 2:</p>
<blockquote>
<p>A <tt>codecvt</tt> facet that is used by <tt>basic_filebuf</tt>
(27.8 ) must have the property that if</p>
<pre>
do_out(state, from, from_end, from_next, to, to_lim, to_next)
</pre>
would succeed (return value would be <tt>ok</tt>), where
<tt>from != from_end</tt>, then
<pre>
do_out(state, from, from + 1, from_next, to, to_end, to_next)
</pre>
must also succeed, and that if
<pre>
do_in(state, from, from_end, from_next, to, to_lim, to_next)
</pre>
would succeed, where <tt>to != to_lim</tt>, then
<pre>
do_in(state, from, from_end, from_next, to, to + 1, to_next)
</pre>
<p>must also succeed. [<i>Footnote:</i> Informally, this means that
<tt>basic_filebuf</tt> assumes that the mapping from internal to
external characters is 1 to N: a <tt>codecvt</tt> that is used by
<tt>basic_filebuf</tt> must be able to translate characters one
internal character at a time. <i>--End Footnote</i>]</p>
</blockquote>
<p><b>Rationale:</b></p>
<p>The proposed resoluion says that conversions can be performed one
internal character at a time. This rules out some encodings that
would otherwise be legal. The alternative answer would mean there
would be some internal positions that do not correspond to any
external file position.</p>
<p>
An example of an encoding that this rules out is one where the
<tt>internT</tt> and <tt>externT</tt> are of the same type, and
where the internal sequence <tt>c1 c2</tt> corresponds to the
external sequence <tt>c2 c1</tt>.
</p>
<p>It was generally agreed that <tt>basic_filebuf</tt> relies
on this property: it was designed under the assumption that
the external-to-internal mapping is N-to-1, and it is not clear
that <tt>basic_filebuf</tt> is implementable without that
restriction.
</p>
<p>
The proposed resolution is expressed as a restriction on
<tt>codecvt</tt> when used by <tt>basic_filebuf</tt>, rather
than a blanket restriction on all <tt>codecvt</tt> facets,
because <tt>basic_filebuf</tt> is the only other part of the
library that uses <tt>codecvt</tt>. If a user wants to define
a <tt>codecvt</tt> facet that implements a more general N-to-M
mapping, there is no reason to prohibit it, so long as the user
does not expect <tt>basic_filebuf</tt> to be able to use it.
</p>
<hr>
<a name="91"><h3>91.&nbsp;Description of operator&gt;&gt; and getline() for string&lt;&gt; might cause endless loop</h3></a><p>
<b>Section:</b>&nbsp;21.3.7.9 <a href="lib-strings.html#lib.string.io"> [lib.string.io]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Nico Josuttis&nbsp; <b>Date:</b>&nbsp;29 Sep 1998</p>
<p>Operator &gt;&gt; and getline() for strings read until eof()
in the input stream is true. However, this might never happen, if the
stream can't read anymore without reaching EOF. So shouldn't it be
changed into that it reads until !good() ? </p>
<p><b>Proposed resolution:</b></p>
<p>In 21.3.7.9 , paragraph 1, replace:</p>
<blockquote>
Effects: Begins by constructing a sentry object k as if k were
constructed by typename basic_istream&lt;charT,traits&gt;::sentry k( is). If
bool( k) is true, it calls str.erase() and then extracts characters
from is and appends them to str as if by calling str.append(1, c). If
is.width() is greater than zero, the maximum number n of characters
appended is is.width(); otherwise n is str.max_size(). Characters are
extracted and appended until any of the following occurs:
</blockquote>
<p>with:</p>
<blockquote>
Effects: Behaves as an unformatted input function (27.6.1.2 ). After constructing a sentry object, if the
sentry converts to true, calls str.erase() and then extracts
characters from is and appends them to str as if by calling
str.append(1,c). If is.width() is greater than zero, the maximum
number n of characters appended is is.width(); otherwise n is
str.max_size(). Characters are extracted and appended until any of the
following occurs:
</blockquote>
<p>In 21.3.7.9 , paragraph 6, replace</p>
<blockquote>
Effects: Begins by constructing a sentry object k as if by typename
basic_istream&lt;charT,traits&gt;::sentry k( is, true). If bool( k) is true,
it calls str.erase() and then extracts characters from is and appends
them to str as if by calling str.append(1, c) until any of the
following occurs:
</blockquote>
<p>with:</p>
<blockquote>
Effects: Behaves as an unformatted input function (27.6.1.2 ). After constructing a sentry object, if the
sentry converts to true, calls str.erase() and then extracts
characters from is and appends them to str as if by calling
str.append(1,c) until any of the following occurs:
</blockquote>
<p><b>Rationale:</b></p>
<p>The real issue here is whether or not these string input functions
perform formatted input. If they do, then they get their characters
from a streambuf, rather than by calling an istream's member functions,
and a streambuf signals failure either by returning eof or by throwing
an exception. The proposed resolution makes it clear that these two
functions do perform formatted input.</p>
<hr>
<a name="92"><h3>92.&nbsp;Incomplete Algorithm Requirements</h3></a><p>
<b>Section:</b>&nbsp;25 <a href="lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Nico Josuttis&nbsp; <b>Date:</b>&nbsp;29 Sep 1998</p>
<p>The standard does not state, how often a function object is copied,
called, or the order of calls inside an algorithm. This may lead to
surprising/buggy behavior. Consider the following example: </p>
<pre>class Nth { // function object that returns true for the nth element
private:
int nth; // element to return true for
int count; // element counter
public:
Nth (int n) : nth(n), count(0) {
}
bool operator() (int) {
return ++count == nth;
}
};
....
// remove third element
list&lt;int&gt;::iterator pos;
pos = remove_if(coll.begin(),coll.end(), // range
Nth(3)), // remove criterion
coll.erase(pos,coll.end()); </pre>
<p>This call, in fact removes the 3rd <b>AND the 6th</b> element. This
happens because the usual implementation of the algorithm copies the
function object internally: </p>
<pre>template &lt;class ForwIter, class Predicate&gt;
ForwIter std::remove_if(ForwIter beg, ForwIter end, Predicate op)
{
beg = find_if(beg, end, op);
if (beg == end) {
return beg;
}
else {
ForwIter next = beg;
return remove_copy_if(++next, end, beg, op);
}
} </pre>
<p>The algorithm uses find_if() to find the first element that should
be removed. However, it then uses a copy of the passed function object
to process the resulting elements (if any). Here, Nth is used again
and removes also the sixth element. This behavior compromises the
advantage of function objects being able to have a state. Without any
cost it could be avoided (just implement it directly instead of
calling find_if()). </p>
<p><b>Proposed resolution:</b></p>
<p> In [lib.function.objects] 20.3 Function objects add as new
paragraph 6 (or insert after paragraph 1): </p>
<p>Option 1: </p>
<blockquote>
Predicates are functions or function objects that fulfill the
following requirements:<br> &nbsp; - They return a Boolean value (bool
or a value convertible to bool)<br> &nbsp; - It doesn't matter for the
behavior of a predicate how often it is copied or assigned and how
often it is called.
</blockquote>
<p>Option 2: </p>
<blockquote>
- if it's a function:<br> &nbsp; - All calls with the same
argument values yield the same result.<br> - if it's a function
object:<br> &nbsp; - In any sequence of calls to operator () without
calling any non-constant member function, all calls with the same
argument values yield the same result.&nbsp;<br> - After an assignment
or copy both objects return the same result for the same values.
</blockquote>
<p><i>[Santa Cruz: The LWG believes that there may be more to this than
meets the eye. It applies to all function objects, particularly
predicates. Two questions: (1) must a function object be
copyable? (2) how many times is a function object called?&nbsp; These
are in effect questions about state.&nbsp; Function objects appear to
require special copy semantics to make state work, and may fail if
calling alters state and calling occurs an unexpected number of
times.]</i></p>
<p><i>[Dublin: Pete Becker felt that this may not be a defect,
but rather something that programmers need to be educated about.
There was discussion of adding wording to the effect that the number
and order of calls to function objects, including predicates, not
affect the behavior of the function object.]</i></p>
<p><i>[Pre-Kona: Nico comments: It seems the problem is that we don't
have a clear statement of &quot;predicate&quot; in the
standard. People including me seemed to think &quot;a function
returning a Boolean value and being able to be called by an STL
algorithm or be used as sorting criterion or ... is a
predicate&quot;. But a predicate has more requirements: It should
never change its behavior due to a call or being copied. IMHO we have
to state this in the standard. If you like, see section 8.1.4 of my
library book for a detailed discussion.]</i></p>
<p><i>[Kona: Nico will provide wording to the effect that &quot;unless
otherwise specified, the number of copies of and calls to function
objects by algorithms is unspecified&quot;.&nbsp; Consider placing in
25 after paragraph 9.]</i></p>
<p><i>[Pre-Tokyo: Angelika Langer comments: if the resolution is
that algorithms are free to copy and pass around any function objects,
then it is a valid question whether they are also allowed to change
the type information from reference type to value type.]</i></p>
<p><i>[Tokyo: Nico will discuss this further with Matt as there are
multiple problems beyond the underlying problem of no definition of
&quot;Predicate&quot;.]</i></p>
<p><i>[Post-Tokyo: Nico provided the above proposed
resolutions.]</i></p>
<hr>
<a name="96"><h3>96.&nbsp;Vector&lt;bool&gt; is not a container</h3></a><p>
<b>Section:</b>&nbsp;23.2.5 <a href="lib-containers.html#lib.vector.bool"> [lib.vector.bool]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;AFNOR&nbsp; <b>Date:</b>&nbsp;7 Oct 1998</p>
<p>
<tt>vector&lt;bool&gt;</tt> is not a container as its reference and
pointer types are not references and pointers. </p>
<p>Also it forces everyone to have a space optimization instead of a
speed one.</p>
<p>
<b>See also:</b> 99-0008 == N1185 Vector&lt;bool&gt; is
Nonconforming, Forces Optimization Choice.</p>
<p><b>Proposed resolution:</b></p>
<p><i>[In Santa Cruz the LWG felt that this was Not A Defect.]</i></p>
<p><i>[In Dublin many present felt that failure to meet Container
requirements was a defect. There was disagreement as to whether
or not the optimization requirements constituted a defect.]</i></p>
<p><i>[The LWG looked at the following resolutions in some detail:
<br>
&nbsp;&nbsp;&nbsp;&nbsp; * Not A Defect.<br>
&nbsp;&nbsp;&nbsp;&nbsp; * Add a note explaining that vector&lt;bool&gt; does not meet
Container requirements.<br>
&nbsp;&nbsp;&nbsp;&nbsp; * Remove vector&lt;bool&gt;.<br>
&nbsp;&nbsp;&nbsp;&nbsp; * Add a new category of container requirements which
vector&lt;bool&gt; would meet.<br>
&nbsp;&nbsp;&nbsp;&nbsp; * Rename vector&lt;bool&gt;.<br>
<br>
No alternative had strong, wide-spread, support and every alternative
had at least one &quot;over my dead body&quot; response.<br>
<br>
There was also mention of a transition scheme something like (1) add
vector_bool and deprecate vector&lt;bool&gt; in the next standard. (2)
Remove vector&lt;bool&gt; in the following standard.]</i></p>
<p><i>[Modifying container requirements to permit returning proxies
(thus allowing container requirements conforming vector&lt;bool&gt;)
was also discussed.]</i></p>
<p><i>[It was also noted that there is a partial but ugly workaround in
that vector&lt;bool&gt; may be further specialized with a customer
allocator.]</i></p>
<p><i>[Kona: Herb Sutter presented his paper J16/99-0035==WG21/N1211,
vector&lt;bool&gt;: More Problems, Better Solutions. Much discussion
of a two step approach: a) deprecate, b) provide replacement under a
new name. LWG straw vote on that: 1-favor, 11-could live with, 2-over
my dead body. This resolution was mentioned in the LWG report to the
full committee, where several additional committee members indicated
over-my-dead-body positions.]</i></p>
<p><i>[Tokyo: Not discussed by the full LWG; no one claimed new
insights and so time was more productively spent on other issues. In
private discussions it was asserted that requirements for any solution
include 1) Increasing the full committee's understanding of the
problem, and 2) providing compiler vendors, authors, teachers, and of
course users with specific suggestions as to how to apply the eventual
solution.]</i></p>
<hr>
<a name="98"><h3>98.&nbsp;Input iterator requirements are badly written</h3></a><p>
<b>Section:</b>&nbsp;24.1.1 <a href="lib-iterators.html#lib.input.iterators"> [lib.input.iterators]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;AFNOR&nbsp; <b>Date:</b>&nbsp;7 Oct 1998</p>
<p>Table 72 in 24.1.1 specifies semantics for
<tt>*r++</tt> of:</p>
<p>&nbsp;&nbsp; <tt>{ T tmp = *r; ++r; return tmp; }</tt>
</p>
<p>This does not work for pointers and over constrains implementors.</p>
<p><b>Proposed resolution:</b></p>
<p>Add for *r++: &#x93;To call the copy constructor for the type T is
allowed but not required.&#x94;</p>
<p><i>[Dublin: Pete Becker will attempt improved wording.]</i></p>
<p><i>[Tokyo: The essence of the issue seems to have escaped.
Pete will email Valentin to try to recapture it.]</i></p>
<hr>
<a name="109"><h3>109.&nbsp;Missing binders for non-const sequence elements</h3></a><p>
<b>Section:</b>&nbsp;20.3.6 <a href="lib-utilities.html#lib.binders"> [lib.binders]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Bjarne Stroustrup&nbsp; <b>Date:</b>&nbsp;7 Oct 1998</p>
<p>There are no versions of binders that apply to non-const elements
of a sequence. This makes examples like for_each() using bind2nd() on
page 521 of &quot;The C++ Programming Language (3rd)&quot;
non-conforming. Suitable versions of the binders need to be added.</p>
<p>Further discussion from Nico:</p>
<p>What is probably meant here is shown in the following example:</p>
<pre>class Elem {
public:
void print (int i) const { }
void modify (int i) { }
}; </pre>
<pre>int main()
{
vector&lt;Elem&gt; coll(2);
for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&amp;Elem::print),42)); // OK
for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&amp;Elem::modify),42)); // ERROR
}</pre>
<p>The error results from the fact that bind2nd() passes its first
argument (the argument of the sequence) as constant reference. See the
following typical implementation:</p>
<blockquote>
<pre>template &lt;class Operation&gt;
class binder2nd
: public unary_function&lt;typename Operation::first_argument_type,
typename Operation::result_type&gt; {
protected:
Operation op;
typename Operation::second_argument_type value;
public:
binder2nd(const Operation&amp; o,
const typename Operation::second_argument_type&amp; v)
: op(o), value(v) {} </pre>
<pre> typename Operation::result_type
operator()(const typename Operation::first_argument_type&amp; x) const {
return op(x, value);
}
};</pre>
</blockquote>
<p>The solution is to overload operator () of bind2nd for non-constant arguments:</p>
<blockquote>
<pre>template &lt;class Operation&gt;
class binder2nd
: public unary_function&lt;typename Operation::first_argument_type,
typename Operation::result_type&gt; {
protected:
Operation op;
typename Operation::second_argument_type value;
public:
binder2nd(const Operation&amp; o,
const typename Operation::second_argument_type&amp; v)
: op(o), value(v) {} </pre>
<pre> typename Operation::result_type
operator()(const typename Operation::first_argument_type&amp; x) const {
return op(x, value);
}
typename Operation::result_type
operator()(typename Operation::first_argument_type&amp; x) const {
return op(x, value);
}
};</pre>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p>In 20.3.6.1 in the declaration of binder1st after:</p>
<blockquote>
<p><tt>typename Operation::result_type<br>
&nbsp;operator()(const typename Operation::second_argument_type&amp; x) const;</tt></p>
</blockquote>
<p>insert:</p>
<blockquote>
<p><tt>typename Operation::result_type<br>
&nbsp;operator()(typename Operation::second_argument_type&amp; x) const;</tt></p>
</blockquote>
<p>In 20.3.6.3 in the declaration of binder2nd after:</p>
<blockquote>
<p><tt>typename Operation::result_type<br>
&nbsp;operator()(const typename Operation::first_argument_type&amp; x) const;</tt></p>
</blockquote>
<p>insert:</p>
<blockquote>
<p><tt>typename Operation::result_type<br>
&nbsp;operator()(typename Operation::first_argument_type&amp; x) const;</tt></p>
</blockquote>
<p><i>[Kona: The LWG discussed this at some length.It was agreed that
this is a mistake in the design, but there was no consensus on whether
it was a defect in the Standard. Straw vote: NAD - 5. Accept
proposed resolution - 3. Leave open - 6.]</i></p>
<p><i>[Copenhagen: It was generally agreed that this was a defect.
Strap poll: NAD - 0. Accept proposed resolution - 10.
Leave open - 1.]</i></p>
<hr>
<a name="117"><h3>117.&nbsp;<tt>basic_ostream</tt> uses nonexistent <tt>num_put</tt> member functions</h3></a><p>
<b>Section:</b>&nbsp;27.6.2.5.2 <a href="lib-iostreams.html#lib.ostream.inserters.arithmetic"> [lib.ostream.inserters.arithmetic]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;20 Nov 1998</p>
<p>The <b>effects</b> clause for numeric inserters says that
insertion of a value <tt>x</tt>, whose type is either <tt>bool</tt>,
<tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, <tt>unsigned
int</tt>, <tt>long</tt>, <tt>unsigned long</tt>, <tt>float</tt>,
<tt>double</tt>, <tt>long double</tt>, or <tt>const void*</tt>, is
delegated to <tt>num_put</tt>, and that insertion is performed as if
through the following code fragment: </p>
<pre>bool failed = use_facet&lt;
num_put&lt;charT,ostreambuf_iterator&lt;charT,traits&gt; &gt;
&gt;(getloc()).put(*this, *this, fill(), val). failed();</pre>
<p>This doesn't work, because <tt>num_put&lt;&gt;</tt>::put is only
overloaded for the types <tt>bool</tt>, <tt>long</tt>, <tt>unsigned
long</tt>, <tt>double</tt>, <tt>long double</tt>, and <tt>const
void*</tt>. That is, the code fragment in the standard is incorrect
(it is diagnosed as ambiguous at compile time) for the types
<tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, <tt>unsigned
int</tt>, and <tt>float</tt>. </p>
<p>We must either add new member functions to <tt>num_put</tt>, or
else change the description in <tt>ostream</tt> so that it only calls
functions that are actually there. I prefer the latter. </p>
<p><b>Proposed resolution:</b></p>
<p>Replace 27.6.2.5.2, paragraph 1 with the following: </p>
<blockquote>
<p>
The classes num_get&lt;&gt; and num_put&lt;&gt; handle locale&shy;dependent numeric
formatting and parsing. These inserter functions use the imbued
locale value to perform numeric formatting. When val is of type bool,
long, unsigned long, double, long double, or const void*, the
formatting conversion occurs as if it performed the following code
fragment:
</p>
<pre>
bool failed = use_facet&lt;
num_put&lt;charT,ostreambuf_iterator&lt;charT,traits&gt; &gt;
&gt;(getloc()).put(*this, *this, fill(), val). failed();
</pre>
<p>
When val is of type short the formatting conversion occurs as if it
performed the following code fragment:
</p>
<pre>
ios_base::fmtflags baseflags = ios_base::flags() &amp; ios_base::basefield;
bool failed = use_facet&lt;
num_put&lt;charT,ostreambuf_iterator&lt;charT,traits&gt; &gt;
&gt;(getloc()).put(*this, *this, fill(),
baseflags == ios_base::oct || baseflags == ios_base::hex
? static_cast&lt;long&gt;(static_cast&lt;unsigned short&gt;(val))
: static_cast&lt;long&gt;(val)). failed();
</pre>
<p>
When val is of type int the formatting conversion occurs as if it performed
the following code fragment:
</p>
<pre>
ios_base::fmtflags baseflags = ios_base::flags() &amp; ios_base::basefield;
bool failed = use_facet&lt;
num_put&lt;charT,ostreambuf_iterator&lt;charT,traits&gt; &gt;
&gt;(getloc()).put(*this, *this, fill(),
baseflags == ios_base::oct || baseflags == ios_base::hex
? static_cast&lt;long&gt;(static_cast&lt;unsigned int&gt;(val))
: static_cast&lt;long&gt;(val)). failed();
</pre>
<p>
When val is of type unsigned short or unsigned int the formatting conversion
occurs as if it performed the following code fragment:
</p>
<pre>
bool failed = use_facet&lt;
num_put&lt;charT,ostreambuf_iterator&lt;charT,traits&gt; &gt;
&gt;(getloc()).put(*this, *this, fill(), static_cast&lt;unsigned long&gt;(val)).
failed();
</pre>
<p>
When val is of type float the formatting conversion occurs as if it
performed the following code fragment:
</p>
<pre>
bool failed = use_facet&lt;
num_put&lt;charT,ostreambuf_iterator&lt;charT,traits&gt; &gt;
&gt;(getloc()).put(*this, *this, fill(), static_cast&lt;double&gt;(val)).
failed();
</pre>
</blockquote>
<p><i>[post-Toronto: This differs from the previous proposed
resolution; PJP provided the new wording. The differences are in
signed short and int output.]</i></p>
<p><b>Rationale:</b></p>
<p>The original proposed resolution was to cast int and short to long,
unsigned int and unsigned short to unsigned long, and float to double,
thus ensuring that we don't try to use nonexistent num_put&lt;&gt;
member functions. The current proposed resolution is more
complicated, but gives more expected results for hex and octal output
of signed short and signed int. (On a system with 16-bit short, for
example, printing short(-1) in hex format should yield 0xffff.)</p>
<hr>
<a name="120"><h3>120.&nbsp;Can an implementor add specializations?</h3></a><p>
<b>Section:</b>&nbsp;17.4.3.1 <a href="lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Judy Ward&nbsp; <b>Date:</b>&nbsp;15 Dec 1998</p>
<p>Section 17.4.3.1 says: </p>
<blockquote>
<p>It is undefined for a C++ program to add declarations or definitions to namespace std
or namespaces within namespace std unless otherwise specified. A program may add template
specializations for any standard library template to namespace std. Such a specialization
(complete or partial) of a standard library template results in undefined behavior unless
the declaration depends on a user-defined name of external linkage and unless the
specialization meets the standard library requirements for the original template... </p>
</blockquote>
<p>This implies that it is ok for library users to add specializations, but not
implementors. A user program can actually detect this, for example, the following manual
instantiation will not compile if the implementor has made ctype&lt;wchar_t&gt; a
specialization: </p>
<pre>
#include &lt;locale&gt;
#include &lt;wchar.h&gt;
template class std::ctype&lt;wchar_t&gt;; // can't be specialization
</pre>
<p>
Lib-7047 Matt Austern comments:
</p>
<blockquote>
<p>The status quo is unclear, and probably contradictory. This issue
applies both to explicit instantiations and to specializations, since
it is not permitted to provide both a specialization and an explicit
instantiation.
</p>
<p>
The specialization issue is actually more serious than the
instantiation one.
</p>
</blockquote>
<p>In Copenhagen, core working group decided on a proposed resolution
to core issue 259. Under the proposed resolution, it will be legal
for a translation unit to contain both a specialization and an
explicit instantiation of the same template, provided that the
specialization comes first. In such a case, the explicit
instantiation will be ignored. Further discussion of library issue
120 assumes that the core 259 resolution will be adopted.</p>
<p><b>Proposed resolution:</b></p>
<p>Option 1.</p>
<blockquote>
<p>Append to 17.4.3.1 paragraph 1: </p>
<blockquote>
A program may explicitly instantiate any templates in the standard
library only if the declaration depends on a user-defined name of
external linkage and the instantiation meets the standard library
requirements for the original template.
</blockquote>
</blockquote>
<p>Option 2.</p>
<blockquote>
<p>In light of the resolution to core issue 259, no normative changes
in the library clauses are necessary. Add the following non-normative
note to the end of 17.4.3.1 paragraph 1:</p>
<blockquote>
[<i>Note:</i> A program may explicitly instantiate standard library
templates, even when an explicit instantiation does not depend on
a user-defined name. <i>--end note</i>]
</blockquote>
</blockquote>
<p><i>[Copenhagen: LWG discussed three options. (A) Users may not
explicitly instantiate standard library templates, except on
user-defined types. Consequence: library implementors may freely
specialize or instantiate templates. (B) It is implementation defined
whether users may explicitly instantiate standard library templates on
non-user-defined types. Consequence: library implementors may freely
specialize or instantiate templates, but must document the templates
they have explicitly instantiated. (C) Users may explicitly
instantiate any standard library template. Consequence: library
implementors may freely specialize templates, but may not explicitly
instantiate them. This is a serious burden for implementors; one way
they can manage it is by defining the standard template as a wrapper,
and putting all of the real work in an internal helper class/function.
]</i></p>
<p><i>[Straw poll (first number is favor, second is strongly oppose):
A - 4, 0; B - 0, 9; C - 9, 1. Proposed resolution 1, above, is
option A. (It is the original proposed resolution.) Proposed
resolution 2, above, is option C. Because there was no support
for option B, no wording is provided.]</i></p>
<hr>
<a name="123"><h3>123.&nbsp;Should valarray helper arrays fill functions be const?</h3></a><p>
<b>Section:</b>&nbsp;26.3.5.4 <a href="lib-numerics.html#lib.slice.arr.fill"> [lib.slice.arr.fill]</a>, 26.3.7.4 <a href="lib-numerics.html#lib.gslice.array.fill"> [lib.gslice.array.fill]</a>, 26.3.8.4 <a href="lib-numerics.html#lib.mask.array.fill"> [lib.mask.array.fill]</a>, 26.3.9.4 <a href="lib-numerics.html#lib.indirect.array.fill"> [lib.indirect.array.fill]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Judy Ward&nbsp; <b>Date:</b>&nbsp;15 Dec 1998 </p>
<p>One of the operator= in the valarray helper arrays is const and one
is not. For example, look at slice_array. This operator= in Section
26.3.5.2 is const: </p>
<p>&nbsp;&nbsp;&nbsp; <tt>void operator=(const valarray&lt;T&gt;&amp;) const;</tt> </p>
<p>but this one in Section 26.3.5.4 is not: </p>
<p>&nbsp;&nbsp;&nbsp; <tt>void operator=(const T&amp;); </tt>
</p>
<p>The description of the semantics for these two functions is similar. </p>
<p><b>Proposed resolution:</b></p>
<p>Make the <tt>operator=(const T&amp;)</tt> versions of slice_array, gslice_array,
indirect_array, and mask_array <tt>const</tt> member functions. </p>
<p><i>[Dublin: Pete Becker spoke to Daveed Vandevoorde about this and will work on a
proposed resolution.]</i></p>
<p><i>[Tokyo: Discussed together with the AFNOR paper
00-0023/N1246. The current helper slices now violate language rules
due to a core language change (but most compilers don't check, so the
violation has previously gone undetected). Major surgery is being
asked for in this and other valarray proposals (see issue <a href="lwg-closed.html#77">77</a>Rationale), and a complete design review is needed before
making piecemeal changes. Robert Klarer will work on formulating the
issues.]</i></p>
<hr>
<a name="167"><h3>167.&nbsp;Improper use of <tt>traits_type::length()</tt>
</h3></a><p>
<b>Section:</b>&nbsp;27.6.2.5.4 <a href="lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Dietmar K&uuml;hl&nbsp; <b>Date:</b>&nbsp;20 Jul 1999</p>
<p>Paragraph 4 states that the length is determined using
<tt>traits::length(s)</tt>. Unfortunately, this function is not
defined for example if the character type is <tt>wchar_t</tt> and the
type of <tt>s</tt> is <tt>char const*</tt>. Similar problems exist if
the character type is <tt>char</tt> and the type of <tt>s</tt> is
either <tt>signed char const*</tt> or <tt>unsigned char
const*</tt>.</p>
<p><b>Proposed resolution:</b></p>
<p>Change 27.6.2.5.4 paragraph 4 from:</p>
<blockquote>
<p>Effects: Behaves like an formatted inserter (as described in
lib.ostream.formatted.reqmts) of out. After a sentry object is
constructed it inserts characters. The number of characters starting
at s to be inserted is traits::length(s). Padding is determined as
described in lib.facet.num.put.virtuals. The traits::length(s)
characters starting at s are widened using out.widen
(lib.basic.ios.members). The widened characters and any required
padding are inserted into out. Calls width(0).</p>
</blockquote>
<p>to:</p>
<blockquote>
<p>Effects: Behaves like an formatted inserter (as described in
lib.ostream.formatted.reqmts) of out. After a sentry object is
constructed it inserts characters. The number len of characters
starting at s to be inserted is</p>
<p>
- traits::length((const char*)s) if the second argument is of type
const charT*<br>
- char_traits&lt;char&gt;::length(s) if the second argument is of
type const char*, const signed char*, or const unsigned char* and
and charT is not char.<br>
</p>
<p>Padding is determined as described in
lib.facet.num.put.virtuals. The len characters starting at s are
widened using out.widen (lib.basic.ios.members). The widened
characters and any required padding are inserted into out. Calls
width(0).</p>
</blockquote>
<p><i>[Kona: It is clear to the LWG there is a defect here.
Dietmar will supply specific wording.]</i></p>
<p><i>[Post-Tokyo: Dietmar supplied the above wording.]</i></p>
<p><i>[Toronto: The original proposed resolution involved
char_traits&lt;signed char&gt; and char_traits&lt;unsigned char&gt;.
There was strong opposition to requiring that library implementors
provide those specializations of char_traits.]</i></p>
<p><i>[Copenhagen: This still isn't quite right: proposed resolution
text got garbled when the signed char/unsigned char specializations
were removed. Dietmar will provide revised wording.]</i></p>
<hr>
<a name="179"><h3>179.&nbsp;Comparison of const_iterators to iterators doesn't work</h3></a><p>
<b>Section:</b>&nbsp;23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Judy Ward&nbsp; <b>Date:</b>&nbsp;2 Jul 1998</p>
<p>Currently the following will not compile on two well-known standard
library implementations:</p>
<blockquote>
<pre>#include &lt;set&gt;
using namespace std;
void f(const set&lt;int&gt; &amp;s)
{
set&lt;int&gt;::iterator i;
if (i==s.end()); // s.end() returns a const_iterator
}</pre>
</blockquote>
<p>
The reason this doesn't compile is because operator== was implemented
as a member function of the nested classes set:iterator and
set::const_iterator, and there is no conversion from const_iterator to
iterator. Surprisingly, (s.end() == i) does work, though, because of
the conversion from iterator to const_iterator.
</p>
<p>
I don't see a requirement anywhere in the standard that this must
work. Should there be one? If so, I think the requirement would need
to be added to the tables in section 24.1.1. I'm not sure about the
wording. If this requirement existed in the standard, I would think
that implementors would have to make the comparison operators
non-member functions.</p>
<p>This issues was also raised on comp.std.c++ by Darin
Adler.&nbsp; The example given was:</p>
<blockquote>
<pre>bool check_equal(std::deque&lt;int&gt;::iterator i,
std::deque&lt;int&gt;::const_iterator ci)
{
return i == ci;
}</pre>
</blockquote>
<p>Comment from John Potter:</p>
<blockquote>
<p>
In case nobody has noticed, accepting it will break reverse_iterator.
</p>
<p>
The fix is to make the comparison operators templated on two types.
</p>
<pre>
template &lt;class Iterator1, class Iterator2&gt;
bool operator== (reverse_iterator&lt;Iterator1&gt; const&amp; x,
reverse_iterator&lt;Iterator2&gt; const&amp; y);
</pre>
<p>
Obviously: return x.base() == y.base();
</p>
<p>
Currently, no reverse_iterator to const_reverse_iterator compares are
valid.
</p>
<p>
BTW, I think the issue is in support of bad code. Compares should be
between two iterators of the same type. All std::algorithms require
the begin and end iterators to be of the same type.
</p>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p>In section 23.1 after paragraph 7 add:</p>
<blockquote>
<p>It is possible to mix <tt>iterator</tt>s and
<tt>const_iterator</tt>s in iterator comparison and
iterator difference operations.</p>
</blockquote>
<p><i>[Post-Tokyo: Judy supplied the above wording at the request of
the LWG.]</i></p>
<p><i>[post-Toronto: Judy supplied a new proposed resolution. The old
version did not include the words &quot;and iterator
difference&quot;.]</i></p>
<p><i>[Copenhagen: There was some concern that &quot;it is possible
to mix&quot; might be too informal. Howard and Dave will provide new
wording, which will involve a list of expressions that are
guaranteed to be valid.]</i></p>
<p><b>Rationale:</b></p>
<p>
The LWG believes it is clear that the above wording applies only to
the nested types <tt>X::iterator</tt> and <tt>X::const_iterator</tt>,
where <tt>X</tt> is a container. There is no requirement that
<tt>X::reverse_iterator</tt> and <tt>X::const_reverse_iterator</tt>
can be mixed. If mixing them is considered important, that's a
separate issue. (Issue <a href="lwg-active.html#280">280</a>.)
</p>
<hr>
<a name="182"><h3>182.&nbsp;Ambiguous references to size_t</h3></a><p>
<b>Section:</b>&nbsp;17 <a href="lib-intro.html#lib.library"> [lib.library]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Al Stevens&nbsp; <b>Date:</b>&nbsp;15 Aug 1999</p>
<p>Many references to <tt> size_t</tt> throughout the document
omit the <tt> std::</tt> namespace qualification.</p> <p>For
example, 17.4.3.4 paragraph 2:</p>
<blockquote>
<pre>&#x97; operator new(size_t)
&#x97; operator new(size_t, const std::nothrow_t&amp;)
&#x97; operator new[](size_t)
&#x97; operator new[](size_t, const std::nothrow_t&amp;)</pre>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p> In 17.4.3.4 paragraph 2: replace:</p>
<blockquote>
<p><tt> - operator new(size_t)<br>
- operator new(size_t, const std::nothrow_t&amp;)<br>
- operator new[](size_t)<br>
- operator new[](size_t, const std::nothrow_t&amp;)</tt></p>
</blockquote>
<p> by:</p>
<blockquote>
<pre>- operator new(std::size_t)
- operator new(std::size_t, const std::nothrow_t&amp;)
- operator new[](std::size_t)
- operator new[](std::size_t, const std::nothrow_t&amp;)</pre>
</blockquote>
<p>In [lib.allocator.requirements] 20.1.5, paragraph 4: replace:</p>
<blockquote>
<p>The typedef members pointer, const_pointer, size_type, and difference_type
are required to be T*, T const*, size_t, and ptrdiff_t, respectively.</p>
</blockquote>
<p>&nbsp;by:</p>
<blockquote>
<p>The typedef members pointer, const_pointer, size_type, and difference_type
are required to be T*, T const*, std::size_t, and std::ptrdiff_t,
respectively.</p>
</blockquote>
<p>In [lib.allocator.members] 20.4.1.1, paragraphs 3 and 6: replace:</p>
<blockquote>
<p>3 Notes: Uses ::operator new(size_t) (18.4.1).</p>
<p>6 Note: the storage is obtained by calling ::operator new(size_t), but it
is unspecified when or how often this function is called. The use of hint is
unspecified, but intended as an aid to locality if an implementation so
desires.</p>
</blockquote>
<p>by:</p>
<blockquote>
<p>3 Notes: Uses ::operator new(std::size_t) (18.4.1).</p>
<p>6 Note: the storage is obtained by calling ::operator new(std::size_t), but
it is unspecified when or how often this function is called. The use of hint
is unspecified, but intended as an aid to locality if an implementation so
desires.</p>
</blockquote>
<p>In [lib.char.traits.require] 21.1.1, paragraph 1: replace:</p>
<blockquote>
<p>In Table 37, X denotes a Traits class defining types and functions for the
character container type CharT; c and d denote values of type CharT; p and q
denote values of type const CharT*; s denotes a value of type CharT*; n, i and
j denote values of type size_t; e and f denote values of type X::int_type; pos
denotes a value of type X::pos_type; and state denotes a value of type X::state_type.</p>
</blockquote>
<p>by:</p>
<blockquote>
<p>In Table 37, X denotes a Traits class defining types and functions for the
character container type CharT; c and d denote values of type CharT; p and q
denote values of type const CharT*; s denotes a value of type CharT*; n, i and
j denote values of type std::size_t; e and f denote values of type X::int_type;
pos denotes a value of type X::pos_type; and state denotes a value of type X::state_type.</p>
</blockquote>
<p>In [lib.char.traits.require] 21.1.1, table 37: replace the return type of
X::length(p): &quot;size_t&quot; by &quot;std::size_t&quot;.</p>
<p> In [lib.std.iterator.tags] 24.3.3, paragraph 2: replace:<br>
&nbsp;&nbsp;&nbsp; typedef ptrdiff_t difference_type;<br>
by:<br>
&nbsp;&nbsp;&nbsp; typedef std::ptrdiff_t difference_type;</p>
<p> In [lib.locale.ctype] 22.2.1.1 put namespace std { ...} around the declaration of template &lt;class charT&gt; class ctype.<br>
<br>
In [lib.iterator.traits] 24.3.1, paragraph 2 put namespace std { ...} around the declaration of:<br>
<br>
&nbsp;&nbsp;&nbsp; template&lt;class Iterator&gt; struct iterator_traits<br>
&nbsp;&nbsp;&nbsp; template&lt;class T&gt; struct iterator_traits&lt;T*&gt;<br>
&nbsp;&nbsp;&nbsp; template&lt;class T&gt; struct iterator_traits&lt;const T*&gt;</p>
<p><b>Rationale:</b></p>
<p>The LWG believes correcting names like <tt>size_t</tt> and
<tt>ptrdiff_t</tt> to <tt>std::size_t</tt> and <tt>std::ptrdiff_t</tt>
to be essentially editorial. There there can't be another size_t or
ptrdiff_t meant anyway because, according to 17.4.3.1.4 ,</p>
<blockquote>
For each type T from the Standard C library, the types ::T and std::T
are reserved to the implementation and, when defined, ::T shall be
identical to std::T.
</blockquote>
<p>The issue is treated as a Defect Report to make explicit the Project
Editor's authority to make this change.</p>
<p><i>[Post-Tokyo: Nico Josuttis provided the above wording at the
request of the LWG.]</i></p>
<p><i>[Toronto: This is tangentially related to issue <a href="lwg-active.html#229">229</a>, but only tangentially: the intent of this issue is to
address use of the name <tt>size_t</tt> in contexts outside of
namespace std, such as in the description of <tt>::operator new</tt>.
The proposed changes should be reviewed to make sure they are
correct.]</i></p>
<p><i>[pre-Copenhagen: Nico has reviewed the changes and believes
them to be correct.]</i></p>
<hr>
<a name="187"><h3>187.&nbsp;iter_swap underspecified</h3></a><p>
<b>Section:</b>&nbsp;25.2.2 <a href="lib-algorithms.html#lib.alg.swap"> [lib.alg.swap]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Andrew Koenig&nbsp; <b>Date:</b>&nbsp;14 Aug 1999</p>
<p>The description of iter_swap in 25.2.2 paragraph 7,says that it ``exchanges the values''
of the objects to which two iterators refer.<br>
<br>
What it doesn't say is whether it does so using swap or using the assignment operator and copy constructor.<br>
<br>
This question is an important one to answer, because swap is specialized to work efficiently for standard containers.<br>
For example:</p>
<blockquote>
<pre>vector&lt;int&gt; v1, v2;
iter_swap(&amp;v1, &amp;v2);</pre>
</blockquote>
<p>Is this call to iter_swap equivalent to calling swap(v1, v2)?&nbsp; Or is it equivalent to</p>
<blockquote>
<pre>{
vector&lt;int&gt; temp = v1;
v1 = v2;
v2 = temp;
}</pre>
</blockquote>
<p>The first alternative is O(1); the second is O(n).</p>
<p>A LWG member, Dave Abrahams, comments:</p>
<blockquote>
<p>Not an objection necessarily, but I want to point out the cost of that requirement:</p>
<blockquote>
<p><tt>iter_swap(list&lt;T&gt;::iterator, list&lt;T&gt;::iterator)</tt></p>
</blockquote>
<p>can currently be specialized to be more efficient than iter_swap(T*,T*) for many T (by using splicing). Your proposal would make that optimization
illegal.&nbsp;</p>
</blockquote>
<p><i>[Kona: The LWG notes the original need for iter_swap was proxy iterators
which are no longer permitted.]</i></p>
<p><b>Proposed resolution:</b></p>
<p>Change the effect clause of iter_swap in 25.2.2 paragraph 7 from:</p>
<blockquote>
<p>Exchanges the values pointed to by the two iterators a and b.</p>
</blockquote>
<p>to</p>
<blockquote>
<p>
<tt>swap(*a, *b)</tt>.</p>
</blockquote>
<p><i>[post-Toronto: The LWG is concerned about possible
overspecification: there may be cases, such as Dave Abrahams's example
above, and such as vector&lt;bool&gt;'s iterators, where it makes more
sense for iter_swap to do something other than swap. If performance
is a concern, it may be better to have explicit complexity
requirements than to say how iter_swap should be implemented.]</i></p>
<hr>
<a name="197"><h3>197.&nbsp;max_size() underspecified</h3></a><p>
<b>Section:</b>&nbsp;20.1.5 <a href="lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a>, 23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Andy Sawyer&nbsp; <b>Date:</b>&nbsp;21 Oct 1999</p>
<p>Must the value returned by max_size() be unchanged from call to call? </p>
<p>Must the value returned from max_size() be meaningful? </p>
<p>Possible meanings identified in lib-6827: </p>
<p>1) The largest container the implementation can support given &quot;best
case&quot; conditions - i.e. assume the run-time platform is &quot;configured to
the max&quot;, and no overhead from the program itself. This may possibly
be determined at the point the library is written, but certainly no
later than compile time.<br>
<br>
2) The largest container the program could create, given &quot;best case&quot;
conditions - i.e. same platform assumptions as (1), but take into
account any overhead for executing the program itself. (or, roughly
&quot;storage=storage-sizeof(program)&quot;). This does NOT include any resource
allocated by the program. This may (or may not) be determinable at
compile time.<br>
<br>
3) The largest container the current execution of the program could
create, given knowledge of the actual run-time platform, but again,
not taking into account any currently allocated resource. This is
probably best determined at program start-up.<br>
<br>
4) The largest container the current execution program could create at
the point max_size() is called (or more correctly at the point
max_size() returns :-), given it's current environment (i.e. taking
into account the actual currently available resources). This,
obviously, has to be determined dynamically each time max_size() is
called. </p>
<p><b>Proposed resolution:</b></p>
<p>Change 20.1.5 table 32 max_size() wording from:<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the largest value that can meaningfully be
passed to X::allocate<br>
to:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the value of the largest constant expression
(5.19 ) that could ever meaningfully be passed to X::allocate</p>
<p>
Change 23.1 table 65 max_size() wording from:<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size() of the largest possible container.<br>
to:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the value of the largest constant expression
(5.19 ) that could ever meaningfully be returned by X::size().
</p>
<p><i>[Kona: The LWG informally discussed this and asked Andy Sawyer to submit
an issue.]</i></p>
<p><i>[Tokyo: The LWG believes (1) above is the intended meaning.]</i></p>
<p><i>[Post-Tokyo: Beman Dawes supplied the above resolution at the
request of the LWG. 21.3.3 was not changed because it
references max_size() in 23.1. The term &quot;compile-time&quot; was
avoided because it is not defined anywhere in the standard (even
though it is used several places in the library clauses).]</i></p>
<p><i>[Copenhagen: Exactly what <tt>max_size</tt> means is still
unclear. It may have a different meaning as a container member
function than as an allocator member function. For the latter,
it is probably best thought of as an architectural limit.
Nathan will provide new wording.]</i></p>
<hr>
<a name="198"><h3>198.&nbsp;Validity of pointers and references unspecified after iterator destruction</h3></a><p>
<b>Section:</b>&nbsp;24.1 <a href="lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Beman Dawes&nbsp; <b>Date:</b>&nbsp;3 Nov 1999</p>
<p>
Is a pointer or reference obtained from an iterator still valid after
destruction of the iterator?
</p>
<p>
Is a pointer or reference obtained from an iterator still valid after the value
of the iterator changes?
</p>
<blockquote>
<pre>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;iterator&gt;
int main()
{
typedef std::vector&lt;int&gt; vec_t;
vec_t v;
v.push_back( 1 );
// Is a pointer or reference obtained from an iterator still
// valid after destruction of the iterator?
int * p = &amp;*v.begin();
std::cout &lt;&lt; *p &lt;&lt; '\n'; // OK?
// Is a pointer or reference obtained from an iterator still
// valid after the value of the iterator changes?
vec_t::iterator iter( v.begin() );
p = &amp;*iter++;
std::cout &lt;&lt; *p &lt;&lt; '\n'; // OK?
return 0;
}
</pre>
</blockquote>
<p>The standard doesn't appear to directly address these
questions. The standard needs to be clarified. At least two real-world
cases have been reported where library implementors wasted
considerable effort because of the lack of clarity in the
standard. The question is important because requiring pointers and
references to remain valid has the effect for practical purposes of
prohibiting iterators from pointing to cached rather than actual
elements of containers.</p>
<p>The standard itself assumes that pointers and references obtained
from an iterator are still valid after iterator destruction or
change. The definition of reverse_iterator::operator*(), 24.4.1.3.3 , which returns a reference, defines
effects:</p>
<blockquote>
<pre>Iterator tmp = current;
return *--tmp;</pre>
</blockquote>
<p>The definition of reverse_iterator::operator-&gt;(), 24.4.1.3.4 , which returns a pointer, defines effects:</p>
<blockquote>
<pre>return &amp;(operator*());</pre>
</blockquote>
<p>Because the standard itself assumes pointers and references remain
valid after iterator destruction or change, the standard should say so
explicitly. This will also reduce the chance of user code breaking
unexpectedly when porting to a different standard library
implementation.</p>
<p><b>Proposed resolution:</b></p>
<p>Add a new paragraph to 24.1 :</p>
<blockquote>
Destruction of an iterator may invalidate pointers and references
previously obtained from that iterator.
</blockquote>
<p>Replace paragraph 1 of 24.4.1.3.3 with:</p>
<blockquote>
<p><b>Effects:</b></p>
<pre>
this-&gt;tmp = current;
--this-&gt;tmp;
return *this-&gt;tmp;
</pre>
<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.1 .) The name of this member variable is shown for
exposition only. <i>--end note</i>]
</p>
</blockquote>
<p><i>[Tokyo: The LWG reformulated the question purely in terms of
iterators. The answer to the question is &quot;no, pointers and references
don't remain valid after iterator destruction.&quot; PJP explained that
implementors use considerable care to avoid such ephemeral pointers and
references. Several LWG members said that they thought that the standard
did not actually specify the lifetime of pointers and references obtained from
iterators, except possibly input iterators.]</i></p>
<p><i>[Post-Tokyo: The issue has been reformulated purely
in terms of iterators.]</i></p>
<p><i>[Pre-Toronto: Steve Cleary pointed out the no-invalidation
assumption by reverse_iterator. The issue and proposed resolution was
reformulated yet again to reflect this reality.]</i></p>
<p><i>[Copenhagen: Andy Koenig pointed out that it is possible to
rewrite reverse_iterator so that it no longer makes this assumption.
However, this issue is related to issue <a href="lwg-active.html#299">299</a>. If we
decide it is intentional that <tt>p[n]</tt> may return by value
instead of reference when <tt>p</tt> is a Random Access Iterator, then
other changes in reverse_iterator will be necessary.]</i></p>
<hr>
<a name="200"><h3>200.&nbsp;Forward iterator requirements don't allow constant iterators</h3></a><p>
<b>Section:</b>&nbsp;24.1.3 <a href="lib-iterators.html#lib.forward.iterators"> [lib.forward.iterators]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;19 Nov 1999</p>
<p>
In table 74, the return type of the expression <tt>*a</tt> is given
as <tt>T&amp;</tt>, where <tt>T</tt> is the iterator's value type.
For constant iterators, however, this is wrong. (&quot;Value type&quot;
is never defined very precisely, but it is clear that the value type
of, say, <tt>std::list&lt;int&gt;::const_iterator</tt> is supposed to be
<tt>int</tt>, not <tt>const int</tt>.)
</p>
<p><b>Proposed resolution:</b></p>
<p>
In table 74, change the <b>return type</b> column for <tt>*a</tt>
from &quot;<tt>T&amp;</tt>&quot; to &quot;<tt>T&amp;</tt> if
<tt>X</tt> is mutable, otherwise <tt>const T&amp;</tt>&quot;.
</p>
<p><i>[Tokyo: The LWG believes this is the tip of a larger iceberg;
there are multiple const problems with the STL portion of the library
and that these should be addressed as a single package.&nbsp; Note
that issue <a href="lwg-closed.html#180">180</a> has already been declared NAD Future for
that very reason.]</i></p>
<hr>
<a name="201"><h3>201.&nbsp;Numeric limits terminology wrong</h3></a><p>
<b>Section:</b>&nbsp;18.2.1 <a href="lib-support.html#lib.limits"> [lib.limits]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Stephen Cleary&nbsp; <b>Date:</b>&nbsp;21 Dec 1999</p>
<p>
In some places in this section, the terms &quot;fundamental types&quot; and
&quot;scalar types&quot; are used when the term &quot;arithmetic types&quot; is intended.
The current usage is incorrect because void is a fundamental type and
pointers are scalar types, neither of which should have
specializations of numeric_limits.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 18.2 [lib.support.limits] para 1 from:</p>
<blockquote>
<p> The headers &lt;limits&gt;, &lt;climits&gt;, and &lt;cfloat&gt; supply characteristics of implementation-dependent fundamental types (3.9.1).</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> The headers &lt;limits&gt;, &lt;climits&gt;, and &lt;cfloat&gt; supply characteristics of implementation-dependent arithmetic types (3.9.1).</p>
</blockquote>
<p>Change 18.2.1 [lib.limits] para 1 from:</p>
<blockquote>
<p> The numeric_limits component provides a C++ program with information about various properties of the implementation's representation of the fundamental
types.</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> The numeric_limits component provides a C++ program with information about various properties of the implementation's representation of the arithmetic
types.</p>
</blockquote>
<p>Change 18.2.1 [lib.limits] para 2 from:</p>
<blockquote>
<p> Specializations shall be provided for each fundamental type. . .</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> Specializations shall be provided for each arithmetic type. . .</p>
</blockquote>
<p>Change 18.2.1 [lib.limits] para 4 from:</p>
<blockquote>
<p> Non-fundamental standard types. . .</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> Non-arithmetic standard types. . .</p>
</blockquote>
<p>Change 18.2.1.1 [lib.numeric.limits] para 1 from:</p>
<blockquote>
<p> The member is_specialized makes it possible to distinguish between fundamental types, which have specializations, and non-scalar types, which
do not.</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> The member is_specialized makes it possible to distinguish between arithmetic types, which have specializations, and non-arithmetic types,
which do not.</p>
</blockquote>
<p><i>[post-Toronto: The opinion of the LWG is that the wording in the
standard, as well as the wording of the proposed resolution, is
flawed. The term &quot;arithmetic types&quot; is well defined in C
and C++, and it is not clear that the term is being used correctly.
It is also not clear that the term &quot;implementation
dependent&quot; has any useful meaning in this context. The biggest
problem is that numeric_limits seems to be intended both for built-in
types and for user-defined types, and the standard doesn't make it
clear how numeric_limits applies to each of those cases. A wholesale
review of numeric_limits is needed. A paper would be welcome.]</i></p>
<hr>
<a name="202"><h3>202.&nbsp;unique() effects unclear when predicate not an equivalence relation</h3></a><p>
<b>Section:</b>&nbsp;25.2.8 <a href="lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Andrew Koenig&nbsp; <b>Date:</b>&nbsp;13 Jan 2000</p>
<p>
What should unique() do if you give it a predicate that is not an
equivalence relation? There are at least two plausible answers:
</p>
<blockquote>
<p>
1. You can't, because 25.2.8 says that it it &quot;eliminates all but
the first element from every consecutive group of equal
elements...&quot; and it wouldn't make sense to interpret &quot;equal&quot; as
meaning anything but an equivalence relation. [It also doesn't
make sense to interpret &quot;equal&quot; as meaning ==, because then there
would never be any sense in giving a predicate as an argument at
all.]
</p>
<p>
2. The word &quot;equal&quot; should be interpreted to mean whatever the
predicate says, even if it is not an equivalence relation
(and in particular, even if it is not transitive).
</p>
</blockquote>
<p>
The example that raised this question is from Usenet:
</p>
<blockquote>
<pre>int f[] = { 1, 3, 7, 1, 2 };
int* z = unique(f, f+5, greater&lt;int&gt;());</pre>
</blockquote>
<p>
If one blindly applies the definition using the predicate
greater&lt;int&gt;, and ignore the word &quot;equal&quot;, you get:
</p>
<blockquote>
<p>
Eliminates all but the first element from every consecutive group
of elements referred to by the iterator i in the range [first, last)
for which *i &gt; *(i - 1).
</p>
</blockquote>
<p>
The first surprise is the order of the comparison. If we wanted to
allow for the predicate not being an equivalence relation, then we
should surely compare elements the other way: pred(*(i - 1), *i). If
we do that, then the description would seem to say: &quot;Break the
sequence into subsequences whose elements are in strictly increasing
order, and keep only the first element of each subsequence&quot;. So the
result would be 1, 1, 2. If we take the description at its word, it
would seem to call for strictly DEcreasing order, in which case the
result should be 1, 3, 7, 2.<br>
<br>
In fact, the SGI implementation of unique() does neither: It yields 1,
3, 7.
</p>
<p><b>Proposed resolution:</b></p>
<p>Options:</p>
<blockquote>
<p> 1. Impose an explicit requirement that the predicate be an
equivalence relation.&nbsp;</p>
<p> 2. Drop the word &quot;equal&quot; from the description to make it clear that
the intent is to compare pairs of adjacent elements, and
change pred(*i, *(i - 1)) to pred(*(i - 1), i).</p>
<p> 3. Change the effects to:</p>
<blockquote>
Effects: Eliminates all but the first element e from
every consecutive group of elements referred to by the
iterator i in the range [first, last) for which the
following corresponding conditions hold: e == *i or
pred(e,*i) != false.
</blockquote>
</blockquote>
<p>A LWG member, Nico Josuttis, comments:</p>
<p>First, I agree that the current wording is simply wrong. However, to follow
all [known] current implementations I propose [option 3 above].</p>
<p><i>[ Tokyo: The issue was discussed at length without reaching
consensus. Straw vote: Option 1 - preferred by 2 people. Option 2 -
preferred by 0 people. Option 3 - preferred by 3 people. Many
abstentions. ]</i></p>
<p><i>[Copenhagen: There was some support for all options. The option
with the least support was 1 (one person in favor), and the option
with the most support was 2 (seven in favor). One person was strongly
opposed to option 1, and one person was strongly opposed to the
variation on option 2 in which the order of arguments would remain
pred(*i, *(i - 1)).]</i></p>
<hr>
<a name="225"><h3>225.&nbsp;std:: algorithms use of other unqualified algorithms</h3></a><p>
<b>Section:</b>&nbsp;17.4.4.3 <a href="lib-intro.html#lib.global.functions"> [lib.global.functions]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Dave Abrahams&nbsp; <b>Date:</b>&nbsp;01 Apr 2000</p>
<p>Are algorithms in std:: allowed to use other algorithms without qualification, so functions in
user namespaces might be found through Koenig lookup?</p>
<p>For example, a popular standard library implementation includes this
implementation of std::unique:</p>
<blockquote>
<pre>namespace std {
template &lt;class _ForwardIter&gt;
_ForwardIter unique(_ForwardIter __first, _ForwardIter __last) {
__first = adjacent_find(__first, __last);
return unique_copy(__first, __last, __first);
}
}</pre>
</blockquote>
<p>Imagine two users on opposite sides of town, each using unique on his own
sequences bounded by my_iterators . User1 looks at his standard library
implementation and says, &quot;I know how to implement a more efficient
unique_copy for my_iterators&quot;, and writes:</p>
<blockquote>
<pre>namespace user1 {
class my_iterator;
// faster version for my_iterator
my_iterator unique_copy(my_iterator, my_iterator, my_iterator);
}</pre>
</blockquote>
<p>user1::unique_copy() is selected by Koenig lookup, as he intended.</p>
<p>User2 has other needs, and writes:</p>
<blockquote>
<pre>namespace user2 {
class my_iterator;
// Returns true iff *c is a unique copy of *a and *b.
bool unique_copy(my_iterator a, my_iterator b, my_iterator c);
}</pre>
</blockquote>
<p>User2 is shocked to find later that his fully-qualified use of
std::unique(user2::my_iterator, user2::my_iterator, user2::my_iterator) fails to
compile (if he's lucky). Looking in the standard, he sees the following Effects
clause for unique():</p>
<blockquote>
<p>Effects: Eliminates all but the first element from every consecutive group
of equal elements referred to by the iterator i in the range [first, last) for
which the following corresponding conditions hold: *i == *(i - 1) or pred(*i,
*(i - 1)) != false</p>
</blockquote>
<p>The standard gives user2 absolutely no reason to think he can interfere with
std::unique by defining names in namespace user2. His standard library has been
built with the template export feature, so he is unable to inspect the
implementation. User1 eventually compiles his code with another compiler, and
his version of unique_copy silently stops being called. Eventually, he realizes
that he was depending on an implementation detail of his library and had no
right to expect his unique_copy() to be called portably.</p>
<p>On the face of it, and given above scenario, it may seem obvious that the
implementation of unique() shown is non-conforming because it uses unique_copy()
rather than ::std::unique_copy(). Most standard library implementations,
however, seem to disagree with this notion.</p>
<p> <i>[Tokyo:&nbsp; Steve Adamczyk from
the core working group indicates that &quot;std::&quot; is sufficient;&nbsp;
leading &quot;::&quot; qualification is not required because any namespace
qualification is sufficient to suppress Koenig lookup.]</i>
</p>
<p><b>Proposed resolution:</b></p>
<p>Add a paragraph and a note at the end of
17.4.4.3 :</p>
<blockquote>
<p>Unless otherwise specified, no global or non-member function in the
standard library shall use a function from another namespace which is
found through <i>argument-dependent name lookup</i> (3.4.2 ).</p>
<p>[Note: the phrase &quot;unless otherwise specified&quot; is intended to
allow Koenig lookup in cases like that of ostream_iterators:<br>
<br>
Effects:</p>
<blockquote>
<p>*out_stream &lt;&lt; value;<br>
if(delim != 0) *out_stream &lt;&lt; delim;<br>
return (*this);</p>
<p>--end note]</p>
</blockquote>
</blockquote>
<p><i>[Tokyo: The LWG agrees that this is a defect in the standard, but
is as yet unsure if the proposed resolution is the best
solution. Furthermore, the LWG believes that the same problem of
unqualified library names applies to wording in the standard itself,
and has opened issue <a href="lwg-active.html#229">229</a> accordingly. Any resolution of
issue <a href="lwg-active.html#225">225</a> should be coordinated with the resolution of
issue <a href="lwg-active.html#229">229</a>.]</i></p>
<p><i>[Toronto: The LWG is not sure if this is a defect in the
standard. Most LWG members believe that an implementation of
<tt>std::unique</tt> like the one quoted in this issue is already
illegal, since, under certain circumstances, its semantics are not
those specified in the standard. The standard's description of
<tt>unique</tt> does not say that overloading <tt>adjacent_find</tt>
should have any effect.]</i></p>
<hr>
<a name="226"><h3>226.&nbsp;User supplied specializations or overloads of namespace std function templates</h3></a><p>
<b>Section:</b>&nbsp;17.4.3.1 <a href="lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Dave Abrahams&nbsp; <b>Date:</b>&nbsp;01 Apr 2000</p>
<p>The issues are:&nbsp;</p>
<p>1. How can a 3rd party library implementor (lib1) write a version of a standard
algorithm which is specialized to work with his own class template?&nbsp;</p>
<p>2. How can another library implementor (lib2) write a generic algorithm which
will take advantage of the specialized algorithm in lib1?</p>
<p>This appears to be the only viable answer under current language rules:</p>
<blockquote>
<pre>namespace lib1
{
// arbitrary-precision numbers using T as a basic unit
template &lt;class T&gt;
class big_num { //...
};
</pre>
<pre> // defining this in namespace std is illegal (it would be an
// overload), so we hope users will rely on Koenig lookup
template &lt;class T&gt;
void swap(big_int&lt;T&gt;&amp;, big_int&lt;T&gt;&amp;);
}</pre>
<pre>#include &lt;algorithm&gt;
namespace lib2
{
template &lt;class T&gt;
void generic_sort(T* start, T* end)
{
...
// using-declaration required so we can work on built-in types
using std::swap;
// use Koenig lookup to find specialized algorithm if available
swap(*x, *y);
}
}</pre>
</blockquote>
<p>This answer has some drawbacks. First of all, it makes writing lib2 difficult
and somewhat slippery. The implementor needs to remember to write the
using-declaration, or generic_sort will fail to compile when T is a built-in
type. The second drawback is that the use of this style in lib2 effectively
&quot;reserves&quot; names in any namespace which defines types which may
eventually be used with lib2. This may seem innocuous at first when applied to
names like swap, but consider more ambiguous names like unique_copy() instead.
It is easy to imagine the user wanting to define these names differently in his
own namespace. A definition with semantics incompatible with the standard
library could cause serious problems (see issue <a href="lwg-active.html#225">225</a>).</p>
<p>Why, you may ask, can't we just partially specialize std::swap()? It's
because the language doesn't allow for partial specialization of function
templates. If you write:</p>
<blockquote>
<pre>namespace std
{
template &lt;class T&gt;
void swap(lib1::big_int&lt;T&gt;&amp;, lib1::big_int&lt;T&gt;&amp;);
}</pre>
</blockquote>
<p>You have just overloaded std::swap, which is illegal under the current
language rules. On the other hand, the following full specialization is legal:</p>
<blockquote>
<pre>namespace std
{
template &lt;&gt;
void swap(lib1::other_type&amp;, lib1::other_type&amp;);
}</pre>
</blockquote>
<p>This issue reflects concerns raised by the &quot;Namespace issue
with specialized swap&quot; thread on comp.lang.c++.moderated. A
similar set of concerns was earlier raised on the boost.org mailing
list and the ACCU-general mailing list. Also see library reflector
message c++std-lib-7354.</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Tokyo: Summary, &quot;There is no conforming way to extend
std::swap for user defined templates.&quot;&nbsp; The LWG agrees that
there is a problem.&nbsp; Would like more information before
proceeding. This may be a core issue. Core issue 229 has been opened
to discuss the core aspects of this problem. It was also noted that
submissions regarding this issue have been received from several
sources, but too late to be integrated into the issues list.
]</i></p>
<p><i>[Post-Tokyo: A paper with several proposed resolutions,
J16/00-0029==WG21/N1252, &quot;Shades of namespace std functions
&quot; by Alan Griffiths, is in the Post-Tokyo mailing. It
should be considered a part of this issue.]</i></p>
<p><i>[Toronto: Dave Abrahams and Peter Dimov have proposed a
resolution that involves core changes: it would add partial
specialization of function template. The Core Working Group is
reluctant to add partial specialization of function templates. It is
viewed as a large change, CWG believes that proposal presented leaves
some syntactic issues unanswered; if the CWG does add partial
specialization of function templates, it wishes to develop its own
proposal. The LWG continues to believe that there is a serious
problem: there is no good way for users to force the library to use
user specializations of generic standard library functions, and in
certain cases (e.g. transcendental functions called by
<tt>valarray</tt> and <tt>complex</tt>) this is important. Koenig
lookup isn't adequate, since names within the library must be
qualified with <tt>std</tt> (see issue 225), specialization doesn't
work (we don't have partial specialization of function templates), and
users aren't permitted to add overloads within namespace std.
]</i></p>
<p><i>[Copenhagen: Discussed at length, with no consensus. Relevant
papers in the pre-Copenhagen mailing: N1289, N1295, N1296. Discussion
focused on four options. (1) Relax restrictions on overloads within
namespace std. (2) Mandate that the standard library use unqualified
calls for <tt>swap</tt> and possibly other functions. (3) Introduce
helper class templates for <tt>swap</tt> and possibly other functions.
(4) Introduce partial specialization of function templates. Every
option had both support and opposition. Straw poll (first number is
support, second is strongly opposed): (1) 6, 4; (2) 6, 7; (3) 3, 8;
(4) 4, 4.]</i></p>
<hr>
<a name="228"><h3>228.&nbsp;Incorrect specification of &quot;..._byname&quot; facets</h3></a><p>
<b>Section:</b>&nbsp;22.2 <a href="lib-locales.html#lib.locale.categories"> [lib.locale.categories]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Dietmar K&uuml;hl&nbsp; <b>Date:</b>&nbsp;20 Apr 2000</p>
<p>The sections 22.2.1.2 , 22.2.1.4 ,
22.2.1.6 , 22.2.3.2 , 22.2.4.2 , 22.2.5.4 , 22.2.6.4 , and 22.2.7.2 overspecify the
definitions of the &quot;..._byname&quot; classes by listing a bunch
of virtual functions. At the same time, no semantics of these
functions are defined. Real implementations do not define these
functions because the functional part of the facets is actually
implemented in the corresponding base classes and the constructor of
the &quot;..._byname&quot; version just provides suitable date used by
these implementations. For example, the 'numpunct' methods just return
values from a struct. The base class uses a statically initialized
struct while the derived version reads the contents of this struct
from a table. However, no virtual function is defined in
'numpunct_byname'.</p>
<p>For most classes this does not impose a problem but specifically
for 'ctype' it does: The specialization for 'ctype_byname&lt;char&gt;'
is required because otherwise the semantics would change due to the
virtual functions defined in the general version for 'ctype_byname':
In 'ctype&lt;char&gt;' the method 'do_is()' is not virtual but it is
made virtual in both 'ctype&lt;cT&gt;' and 'ctype_byname&lt;cT&gt;'.
Thus, a class derived from 'ctype_byname&lt;char&gt;' can tell whether
this class is specialized or not under the current specification:
Without the specialization, 'do_is()' is virtual while with
specialization it is not virtual.</p>
<p><b>Proposed resolution:</b></p>
<p>&nbsp; Change section 22.2.1.2 (lib.locale.ctype.byname) to become:</p>
<pre> namespace std {
template &lt;class charT&gt;
class ctype_byname : public ctype&lt;charT&gt; {
public:
typedef ctype&lt;charT&gt;::mask mask;
explicit ctype_byname(const char*, size_t refs = 0);
protected:
~ctype_byname(); // virtual
};
}</pre>
<p>&nbsp; Change section 22.2.1.6 (lib.locale.codecvt.byname) to become:</p>
<pre> namespace std {
template &lt;class internT, class externT, class stateT&gt;
class codecvt_byname : public codecvt&lt;internT, externT, stateT&gt; {
public:
explicit codecvt_byname(const char*, size_t refs = 0);
protected:
~codecvt_byname(); // virtual
};
}
</pre>
<p>&nbsp; Change section 22.2.3.2 (lib.locale.numpunct.byname) to become:</p>
<pre> namespace std {
template &lt;class charT&gt;
class numpunct_byname : public numpunct&lt;charT&gt; {
// this class is specialized for char and wchar_t.
public:
typedef charT char_type;
typedef basic_string&lt;charT&gt; string_type;
explicit numpunct_byname(const char*, size_t refs = 0);
protected:
~numpunct_byname(); // virtual
};
}</pre>
<p>&nbsp; Change section 22.2.4.2 (lib.locale.collate.byname) to become:</p>
<pre> namespace std {
template &lt;class charT&gt;
class collate_byname : public collate&lt;charT&gt; {
public:
typedef basic_string&lt;charT&gt; string_type;
explicit collate_byname(const char*, size_t refs = 0);
protected:
~collate_byname(); // virtual
};
}</pre>
<p>&nbsp; Change section 22.2.5.2 (lib.locale.time.get.byname) to become:</p>
<pre> namespace std {
template &lt;class charT, class InputIterator = istreambuf_iterator&lt;charT&gt; &gt;
class time_get_byname : public time_get&lt;charT, InputIterator&gt; {
public:
typedef time_base::dateorder dateorder;
typedef InputIterator iter_type</pre>
<pre> explicit time_get_byname(const char*, size_t refs = 0);
protected:
~time_get_byname(); // virtual
};
}</pre>
<p>&nbsp; Change section 22.2.5.4 (lib.locale.time.put.byname) to become:</p>
<pre> namespace std {
template &lt;class charT, class OutputIterator = ostreambuf_iterator&lt;charT&gt; &gt;
class time_put_byname : public time_put&lt;charT, OutputIterator&gt;
{
public:
typedef charT char_type;
typedef OutputIterator iter_type;</pre>
<pre> explicit time_put_byname(const char*, size_t refs = 0);
protected:
~time_put_byname(); // virtual
};
}&quot;</pre>
<p>&nbsp; Change section 22.2.6.4 (lib.locale.moneypunct.byname) to become:</p>
<pre> namespace std {
template &lt;class charT, bool Intl = false&gt;
class moneypunct_byname : public moneypunct&lt;charT, Intl&gt; {
public:
typedef money_base::pattern pattern;
typedef basic_string&lt;charT&gt; string_type;</pre>
<pre> explicit moneypunct_byname(const char*, size_t refs = 0);
protected:
~moneypunct_byname(); // virtual
};
}</pre>
<p>&nbsp; Change section 22.2.7.2 (lib.locale.messages.byname) to become:</p>
<pre> namespace std {
template &lt;class charT&gt;
class messages_byname : public messages&lt;charT&gt; {
public:
typedef messages_base::catalog catalog;
typedef basic_string&lt;charT&gt; string_type;</pre>
<pre> explicit messages_byname(const char*, size_t refs = 0);
protected:
~messages_byname(); // virtual
};
}</pre>
<p>Remove section 22.2.1.4 completely (because in
this case only those members are defined to be virtual which are
defined to be virtual in 'ctype&lt;cT&gt;'.)</p>
<p><i>[Post-Tokyo: Dietmar K&uuml;hl submitted this issue at the request of
the LWG to solve the underlying problems raised by issue <a href="lwg-closed.html#138">138</a>.]</i></p>
<p><i>[Copenhagen: proposed resolution was revised slightly, to remove
three last virtual functions from <tt>messages_byname</tt>.]</i></p>
<hr>
<a name="229"><h3>229.&nbsp;Unqualified references of other library entities</h3></a><p>
<b>Section:</b>&nbsp;17.4.1.1 <a href="lib-intro.html#lib.contents"> [lib.contents]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Steve Clamage&nbsp; <b>Date:</b>&nbsp;19 Apr 2000</p>
<p>Throughout the library chapters, the descriptions of library entities refer
to other library entities without necessarily qualifying the names.</p>
<p>For example, section 25.2.2 &quot;Swap&quot; describes the effect of
swap_ranges in terms of the unqualified name &quot;swap&quot;. This section
could reasonably be interpreted to mean that the library must be implemented so
as to do a lookup of the unqualified name &quot;swap&quot;, allowing users to
override any ::std::swap function when Koenig lookup applies.</p>
<p>Although it would have been best to use explicit qualification with
&quot;::std::&quot; throughout, too many lines in the standard would have to be
adjusted to make that change in a Technical Corrigendum.</p>
<p>Issue <a href="lwg-active.html#182">182</a>, which addresses qualification of
<tt>size_t</tt>, is a special case of this.
</p>
<p><b>Proposed resolution:</b></p>
<p>To section 17.4.1.1 &quot;Library contents&quot; Add the following paragraph:</p>
<blockquote>
<p>Whenever a name x defined in the standard library is mentioned, the name x
is assumed to be fully qualified as ::std::x, unless explicitly described
otherwise. For example, if the Effects section for library function F is
described as calling library function G, the function ::std::G is meant.</p>
</blockquote>
<p><i>[Post-Tokyo: Steve Clamage submitted this issue at the request of
the LWG to solve a problem in the standard itself similar to the
problem within implementations of library identified by issue <a href="lwg-active.html#225">225</a>. Any resolution of issue <a href="lwg-active.html#225">225</a> should be
coordinated with the resolution of this issue.]</i></p>
<p><i>[post-Toronto: Howard is undecided about whether it is
appropriate for all standard library function names referred to in
other standard library functions to be explicitly qualified by
<tt>std</tt>: it is common advice that users should define global
functions that operate on their class in the same namespace as the
class, and this requires argument-dependent lookup if those functions
are intended to be called by library code. Several LWG members are
concerned that valarray appears to require argument-dependent lookup,
but that the wording may not be clear enough to fall under
&quot;unless explicitly described otherwise&quot;.]</i></p>
<hr>
<a name="230"><h3>230.&nbsp;Assignable specified without also specifying CopyConstructible</h3></a><p>
<b>Section:</b>&nbsp;17 <a href="lib-intro.html#lib.library"> [lib.library]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Beman Dawes&nbsp; <b>Date:</b>&nbsp;26 Apr 2000</p>
<p>Issue <a href="lwg-defects.html#227">227</a> identified an instance (std::swap) where
Assignable was specified without also specifying
CopyConstructible. The LWG asked that the standard be searched to
determine if the same defect existed elsewhere.</p>
<p>There are a number of places (see proposed resolution below) where
Assignable is specified without also specifying
CopyConstructible. There are also several cases where both are
specified. For example, 26.4.1 .</p>
<p><b>Proposed resolution:</b></p>
<p>In 23.1 table 65 for value_type:
change &quot;T is Assignable&quot; to &quot;T is CopyConstructible and
Assignable&quot;
</p>
<p>In 23.1.2 table 69 X::key_type; change
&quot;Key is Assignable&quot; to &quot;Key is
CopyConstructible and Assignable&quot;<br>
</p>
<p>In 24.1.2 paragraph 1, change:
</p>
<blockquote>
<p> A class or a built-in type X satisfies the requirements of an
output iterator if X is an Assignable type (23.1) and also the
following expressions are valid, as shown in Table 73:
</p>
</blockquote>
<p>to:
</p>
<blockquote>
<p> A class or a built-in type X satisfies the requirements of an
output iterator if X is a CopyConstructible (20.1.3) and Assignable
type (23.1) and also the following expressions are valid, as shown in
Table 73:
</p>
</blockquote>
<p><i>[Post-Tokyo: Beman Dawes submitted this issue at the request of
the LWG. He asks that the 25.2.4 and 25.2.5 changes be studied carefully, as it is not clear that
CopyConstructible is really a requirement and may be
overspecification.]</i></p>
<p><b>Rationale:</b></p>
<p>The original proposed resolution also included changes to input
iterator, fill, and replace. The LWG believes that those changes are
not necessary. The LWG considered some blanket statement, where an
Assignable type was also required to be Copy Constructible, but
decided against this because fill and replace really don't require the
Copy Constructible property.</p>
<hr>
<a name="231"><h3>231.&nbsp;Precision in iostream?</h3></a><p>
<b>Section:</b>&nbsp;22.2.2.2.2 <a href="lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;James Kanze, Stephen Clamage&nbsp; <b>Date:</b>&nbsp; 25 Apr 2000</p>
<p>What is the following program supposed to output?</p>
<pre>#include &lt;iostream&gt;
int
main()
{
std::cout.setf( std::ios::scientific , std::ios::floatfield ) ;
std::cout.precision( 0 ) ;
std::cout &lt;&lt; 1.23 &lt;&lt; '\n' ;
return 0 ;
}</pre>
<p>From my C experience, I would expect &quot;1e+00&quot;; this is what
<tt>printf(&quot;%.0e&quot; , 1.23 );</tt> does. G++ outputs
&quot;1.000000e+00&quot;.</p>
<p>The only indication I can find in the standard is 22.2.2.2.2/11,
where it says &quot;For conversion from a floating-point type, if
(flags &amp; fixed) != 0 or if str.precision() &gt; 0, then
str.precision() is specified in the conversion specification.&quot;
This is an obvious error, however, fixed is not a mask for a field,
but a value that a multi-bit field may take -- the results of and'ing
fmtflags with ios::fixed are not defined, at least not if
ios::scientific has been set. G++'s behavior corresponds to what might
happen if you do use (flags &amp; fixed) != 0 with a typical
implementation (floatfield == 3 &lt;&lt; something, fixed == 1
&lt;&lt; something, and scientific == 2 &lt;&lt; something).</p>
<p>Presumably, the intent is either (flags &amp; floatfield) != 0, or
(flags &amp; floatfield) == fixed; the first gives something more or
less like the effect of precision in a printf floating point
conversion. Only more or less, of course. In order to implement printf
formatting correctly, you must know whether the precision was
explicitly set or not. Say by initializing it to -1, instead of 6, and
stating that for floating point conversions, if precision &lt; -1, 6
will be used, for fixed point, if precision &lt; -1, 1 will be used,
etc. Plus, of course, if precision == 0 and flags &amp; floatfield ==
0, 1 should be = used. But it probably isn't necessary to emulate all
of the anomalies of printf:-).</p>
<p><b>Proposed resolution:</b></p>
<p>
In 22.2.2.2.2 , paragraph 11, change
&quot;if <tt>(flags &amp; fixed) != 0</tt>&quot; to
&quot;if <tt>(flags &amp; floatfield) == fixed ||
(flags &amp; floatfield) == scientific</tt>&quot;
</p>
<p><b>Rationale:</b></p>
<p>The floatfield determines whether numbers are formatted as if
with %f, %e, or %g. If the <tt>fixed</tt> bit is set, it's %f,
if <tt>scientific</tt> it's %e, and if both bits are set, or
neither, it's %e.</p>
<p>Turning to the C standard, a precision of 0 is meaningful
for %f and %e, but not for %g: for %g, precision 0 is taken
to be the same as precision 1.</p>
<p>The proposed resolution has the effect that the output of
the above program will be &quot;1e+00&quot;.</p>
<hr>
<a name="232"><h3>232.&nbsp;&quot;depends&quot; poorly defined in 17.4.3.1</h3></a><p>
<b>Section:</b>&nbsp;17.4.3.1 <a href="lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Peter Dimov&nbsp; <b>Date:</b>&nbsp;18 Apr 2000</p>
<p>17.4.3.1/1 uses the term &quot;depends&quot; to limit the set of allowed
specializations of standard templates to those that &quot;depend on a
user-defined name of external linkage.&quot;</p>
<p>This term, however, is not adequately defined, making it possible to
construct a specialization that is, I believe, technically legal according to
17.4.3.1/1, but that specializes a standard template for a built-in type such as
'int'.</p>
<p>The following code demonstrates the problem:</p>
<blockquote>
<pre>#include &lt;algorithm&gt;</pre>
<pre>template&lt;class T&gt; struct X
{
typedef T type;
};</pre>
<pre>namespace std
{
template&lt;&gt; void swap(::X&lt;int&gt;::type&amp; i, ::X&lt;int&gt;::type&amp; j);
}</pre>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p>Change &quot;user-defined name&quot; to &quot;user-defined
type&quot;.</p>
<p><b>Rationale:</b></p>
<p>This terminology is used in section 2.5.2 and 4.1.1 of <i>The C++
Programming Language</i>. It disallows the example in the issue,
since the underlying type itself is not user-defined. The only
possible problem I can see is for non-type templates, but there's no
possible way for a user to come up with a specialization for bitset,
for example, that might not have already been specialized by the
implementor?</p>
<p><i>[Toronto: this may be related to issue <a href="lwg-active.html#120">120</a>.]</i></p>
<p><i>[post-Toronto: Judy provided the above proposed resolution and
rationale.]</i></p>
<hr>
<a name="233"><h3>233.&nbsp;Insertion hints in associative containers</h3></a><p>
<b>Section:</b>&nbsp;23.1.2 <a href="lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Andrew Koenig&nbsp; <b>Date:</b>&nbsp;30 Apr 2000</p>
<p>
If <tt>mm</tt> is a multimap and <tt>p</tt> is an iterator
into the multimap, then <tt>mm.insert(p, x)</tt> inserts
<tt>x</tt> into <tt>mm</tt> with <tt>p</tt> as a hint as
to where it should go. Table 69 claims that the execution time is
amortized constant if the insert winds up taking place adjacent to
<tt>p</tt>, but does not say when, if ever, this is guaranteed to
happen. All it says it that <tt>p</tt> is a hint as to where to
insert.
</p>
<p>
The question is whether there is any guarantee about the relationship
between <tt>p</tt> and the insertion point, and, if so, what it
is.
</p>
<p>
I believe the present state is that there is no guarantee: The user
can supply <tt>p</tt>, and the implementation is allowed to
disregard it entirely.
</p>
<p><b>Proposed resolution:</b></p>
<p>
General Idea (Andrew Koenig):
t is inserted at the point closest to (the point immediately
ahead of) p. That would give the user a way of controlling the order
in which elements appear that have equal keys. Doing so would be
particularly easy in two cases that I suspect are common:
</p>
<pre>
mm.insert(mm.begin(), t); // inserts as first element of set of equal keys
mm.insert(mm.end(), t); // inserts as last element of set of equal keys
</pre>
<p>
These examples would allow t to be inserted at the beginning and end,
respectively, of the set of elements with the same key as t.
</p>
<p>
assertion/note/pre/postcondition in table 69<br>
Change:
</p>
<blockquote>
iterator p is a hint pointing to where the insert should start to search.
</blockquote>
<p>To:</p>
<blockquote>
if t is inserted, p is used as follows: insert t right before p
if possible; otherwise, if p is equal to a.end(), or if the key value
of t is greater than the key value of *p, t is inserted just before
a.lowerbound(the key value of t); otherwise, t is inserted right
before a.upperbound(the key value of t).
</blockquote>
<p>complexity:<br>
Change:</p>
<blockquote>right after p</blockquote>
<p>To:</p>
<blockquote>right before p</blockquote>
<p>
Thus making:<br>
assertion/note/pre/postcondition:
</p>
<blockquote>
inserts t if and only if there is no element with key equivalent to
the key of t in containers with unique keys; always inserts t in
containers with equivalent keys. always returns the iterator pointing
to the element with key equivalent to the key of t.
if t is inserted, p is used as follows: insert t right before p
if possible; otherwise, if p is equal to a.end(), or if the key value
of t is greater than the key value of *p, t is inserted just before
a.lowerbound(the key value of t); otherwise, t is inserted right
before a.upperbound(the key value of t).
<br>NON-NORMATIVE FOOTNOTE:
| This gives the user a way of controlling the order
| in which elements appear that have equal keys. Doing this is
| particularly easy in two common cases:
<pre>
| mm.insert(mm.begin(), t); // inserts as first element of set of equal keys
| mm.insert(mm.end(), t); // inserts as last element of set of equal keys
</pre>
<br>END-FOOTNOTE
</blockquote>
<p>complexity:</p>
<blockquote>
logarithmic in general, but amortized constant if t is inserted right
before p.
</blockquote>
<p><i>[Toronto: there was general agreement that this is a real defect:
when inserting an element x into a multiset that already contains
several copies of x, there is no way to know whether the hint will be
used. There was some support for an alternative resolution: we check
on both sides of the hint (both before and after, in that order). If
either is the correct location, the hint is used; otherwise it is not.
This would be different from the original proposed resolution, because
in the proposed resolution the hint will be used even if it is very
far from the insertion point. JC van Winkel supplied precise wording
for both options.]</i></p>
<p><i>[Copenhagen: the LWG looked at both options, and preferred the
original. This preference is contingent on seeing a reference
implementation showing that it is possible to implement this
requirement without loss of efficiency.]</i></p>
<hr>
<a name="235"><h3>235.&nbsp;No specification of default ctor for reverse_iterator</h3></a><p>
<b>Section:</b>&nbsp;24.4.1.1 <a href="lib-iterators.html#lib.reverse.iterator"> [lib.reverse.iterator]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Dietmar K&uuml;hl&nbsp; <b>Date:</b>&nbsp;24 Apr 2000</p>
<p>The declaration of <tt>reverse_iterator</tt> lists a default
constructor. However, no specification is given what this constructor
should do.</p>
<p><b>Proposed resolution:</b></p>
<p>In section 24.4.1.3.1 add the following
paragraph:</p>
<blockquote>
<p><tt>reverse_iterator()</tt></p>
<p>Default initializes <tt>current</tt>. Iterator operations
applied to the resulting iterator have defined behavior if and
only if the corresponding operations are defined on a default
constructed iterator of type <tt>Iterator</tt>.</p>
</blockquote>
<p><i>[pre-Copenhagen: Dietmar provide wording for proposed
resolution.]</i></p>
<hr>
<a name="238"><h3>238.&nbsp;Contradictory results of stringbuf initialization.</h3></a><p>
<b>Section:</b>&nbsp;27.7.1.1 <a href="lib-iostreams.html#lib.stringbuf.cons"> [lib.stringbuf.cons]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Dietmar K&uuml;hl&nbsp; <b>Date:</b>&nbsp;11 May 2000</p>
<p>In 27.7.1.1 paragraph 4 the results of calling the constructor of
'basic_stringbuf' are said to be <tt>str() == str</tt>. This is fine
that far but consider this code:</p>
<pre>
std::basic_stringbuf&lt;char&gt; sbuf(&quot;hello, world&quot;, std::ios_base::openmode(0));
std::cout &lt;&lt; &quot;'&quot; &lt;&lt; sbuf.str() &lt;&lt; &quot;'\n&quot;;
</pre>
<p>Paragraph 3 of 27.7.1.1 basically says that in this case neither
the output sequence nor the input sequence is initialized and
paragraph 2 of 27.7.1.2 basically says that <tt>str()</tt> either
returns the input or the output sequence. None of them is initialized,
ie. both are empty, in which case the return from <tt>str()</tt> is
defined to be <tt>basic_string&lt;cT&gt;()</tt>.</p>
<p>However, probably only test cases in some testsuites will detect this
&quot;problem&quot;...</p>
<p><b>Proposed resolution:</b></p>
<p>Remove 27.7.1.1 paragraph 4.</p>
<p><b>Rationale:</b></p>
<p>We could fix 27.7.1.1 paragraph 4, but there would be no point. If
we fixed it, it would say just the same thing as text that's already
in the standard.</p>
<hr>
<a name="239"><h3>239.&nbsp;Complexity of unique() and/or unique_copy incorrect</h3></a><p>
<b>Section:</b>&nbsp;25.2.8 <a href="lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Angelika Langer&nbsp; <b>Date:</b>&nbsp;May 15 2000</p>
<p>The complexity of unique and unique_copy are inconsistent with each
other and inconsistent with the implementations.&nbsp; The standard
specifies:</p>
<p>for unique():</p>
<blockquote>-3- Complexity: If the range (last - first) is not empty, exactly
(last - first) - 1 applications of the corresponding predicate, otherwise
no applications of the predicate.</blockquote>
<p>for unique_copy():</p>
<blockquote>-7- Complexity: Exactly last - first applications of the corresponding
predicate.</blockquote>
<p>
The implementations do it the other way round: unique() applies the
predicate last-first times and unique_copy() applies it last-first-1
times.</p>
<p>As both algorithms use the predicate for pair-wise comparison of
sequence elements I don't see a justification for unique_copy()
applying the predicate last-first times, especially since it is not
specified to which pair in the sequence the predicate is applied
twice.</p>
<p><b>Proposed resolution:</b></p>
<p>Change both complexity sections in 25.2.8 to:</p>
<blockquote>Complexity: Exactly last - first - 1 applications of the
corresponding predicate.</blockquote>
<p><i>[Toronto: This is related to issue <a href="lwg-active.html#202">202</a>. We can't
specify <tt>unique</tt>'s complexity until we decide what
<tt>unique</tt> is supposed to do.]</i></p>
<hr>
<a name="240"><h3>240.&nbsp;Complexity of adjacent_find() is meaningless</h3></a><p>
<b>Section:</b>&nbsp;25.1.5 <a href="lib-algorithms.html#lib.alg.adjacent.find"> [lib.alg.adjacent.find]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Angelika Langer&nbsp; <b>Date:</b>&nbsp;May 15 2000</p>
<p>The complexity section of adjacent_find is defective:</p>
<blockquote>
<pre>
template &lt;class ForwardIterator&gt;
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last
BinaryPredicate pred);
</pre>
<p>-1- Returns: The first iterator i such that both i and i + 1 are in
the range [first, last) for which the following corresponding
conditions hold: *i == *(i + 1), pred(*i, *(i + 1)) != false. Returns
last if no such iterator is found.</p>
<p>-2- Complexity: Exactly find(first, last, value) - first applications
of the corresponding predicate.
</p>
</blockquote>
<p>In the Complexity section, it is not defined what &quot;value&quot;
is supposed to mean. My best guess is that &quot;value&quot; means an
object for which one of the conditions pred(*i,value) or
pred(value,*i) is true, where i is the iterator defined in the Returns
section. However, the value type of the input sequence need not be
equality-comparable and for this reason the term find(first, last,
value) - first is meaningless.</p>
<p>A term such as find_if(first, last, bind2nd(pred,*i)) - first or
find_if(first, last, bind1st(pred,*i)) - first might come closer to
the intended specification. Binders can only be applied to function
objects that have the function call operator declared const, which is
not required of predicates because they can have non-const data
members. For this reason, a specification using a binder could only be
an &quot;as-if&quot; specification.</p>
<p><b>Proposed resolution:</b></p>
<p>Change the complexity section in 25.1.5 to:</p>
<blockquote>
For a nonempty range, exactly <tt>min((<i>i</i> - <i>first</i>) + 1,
(<i>last</i> - <i>first</i>) - 1)</tt> applications of the
corresponding predicate, where <i>i</i> is <tt>adjacent_find</tt>'s
return value.
</blockquote>
<p><i>[Copenhagen: the original resolution specified an upper
bound. The LWG preferred an exact count.]</i></p>
<hr>
<a name="241"><h3>241.&nbsp;Does unique_copy() require CopyConstructible and Assignable?</h3></a><p>
<b>Section:</b>&nbsp;25.2.8 <a href="lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Angelika Langer&nbsp; <b>Date:</b>&nbsp;May 15 2000</p>
<p>Some popular implementations of unique_copy() create temporary
copies of values in the input sequence, at least if the input iterator
is a pointer. Such an implementation is built on the assumption that
the value type is CopyConstructible and Assignable.</p>
<p>It is common practice in the standard that algorithms explicitly
specify any additional requirements that they impose on any of the
types used by the algorithm. An example of an algorithm that creates
temporary copies and correctly specifies the additional requirements
is accumulate(), 26.4.1 .</p>
<p>Since the specifications of unique() and unique_copy() do not
require CopyConstructible and Assignable of the InputIterator's value
type the above mentioned implementations are not standard-compliant. I
cannot judge whether this is a defect in the standard or a defect in
the implementations.</p>
<p><b>Proposed resolution:</b></p>
<p>In 25.2.8 change:</p>
<blockquote>
-4- Requires: The ranges [first, last) and [result, result+(last-first))
shall not overlap.
</blockquote>
<p>to:</p>
<blockquote>
-4- Requires: The ranges [first, last) and [result, result+(last-first))
shall not overlap. The expression *result = *first is valid.
</blockquote>
<p><b>Rationale:</b></p>
<p>
Creating temporary copies is unavoidable, since the arguments may be
input iterators; this implies that the value type must be copy
constructible. However, we don't need to say this explicitly; it's
already implied by table 72 in 24.1.1. We don't precisely want to say
that the input iterator's value type <tt>T</tt> must be assignable,
because we never quite use that property. We assign through the
output iterator. The output iterator might have a different value
type, or no value type; it might not use <tt>T</tt>'s assignment
operator. If it's an <tt>ostream_iterator</tt>, for example, then
we'll use <tt>T</tt>'s operator&lt;&lt; but not its assignment
operator.
</p>
<hr>
<a name="242"><h3>242.&nbsp;Side effects of function objects</h3></a><p>
<b>Section:</b>&nbsp;25.2.3 <a href="lib-algorithms.html#lib.alg.transform"> [lib.alg.transform]</a>, 26.4 <a href="lib-numerics.html#lib.numeric.ops"> [lib.numeric.ops]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Angelika Langer&nbsp; <b>Date:</b>&nbsp;May 15 2000</p>
<p>The algorithms transform(), accumulate(), inner_product(),
partial_sum(), and adjacent_difference() require that the function
object supplied to them shall not have any side effects.</p>
<p>The standard defines a side effect in 1.9 as:</p>
<blockquote>-7- Accessing an object designated by a volatile lvalue (basic.lval),
modifying an object, calling a library I/O function, or calling a function
that does any of those operations are all side effects, which are changes
in the state of the execution environment.</blockquote>
<p>As a consequence, the function call operator of a function object supplied
to any of the algorithms listed above cannot modify data members, cannot
invoke any function that has a side effect, and cannot even create and
modify temporary objects.&nbsp; It is difficult to imagine a function object
that is still useful under these severe limitations. For instance, any
non-trivial transformator supplied to transform() might involve creation
and modification of temporaries, which is prohibited according to the current
wording of the standard.</p>
<p>On the other hand, popular implementations of these algorithms exhibit
uniform and predictable behavior when invoked with a side-effect-producing
function objects. It looks like the strong requirement is not needed for
efficient implementation of these algorithms.</p>
<p>The requirement of&nbsp; side-effect-free function objects could be
replaced by a more relaxed basic requirement (which would hold for all
function objects supplied to any algorithm in the standard library):</p>
<blockquote>A function objects supplied to an algorithm shall not invalidate
any iterator or sequence that is used by the algorithm. Invalidation of
the sequence includes destruction of the sorting order if the algorithm
relies on the sorting order (see section 25.3 - Sorting and related operations
[lib.alg.sorting]).</blockquote>
<p>I can't judge whether it is intended that the function objects supplied
to transform(), accumulate(), inner_product(), partial_sum(), or adjacent_difference()
shall not modify sequence elements through dereferenced iterators.</p>
<p>It is debatable whether this issue is a defect or a change request.
Since the consequences for user-supplied function objects are drastic and
limit the usefulness of the algorithms significantly I would consider it
a defect.</p>
<p><b>Proposed resolution:</b></p>
<p><i>Things to notice about these changes:</i></p>
<ol>
<li> <i>The fully-closed (&quot;[]&quot; as opposed to half-closed &quot;[)&quot; ranges
are intentional. we want to prevent side-effects from
invalidating the end iterators.</i>
</li>
<li> <i>That has the unintentional side-effect of prohibiting
modification of the end element as a side-effect. This could
conceivably be significant in some cases.</i>
</li>
<li> <i>The wording also prevents side-effects from modifying elements
of the output sequence. I can't imagine why anyone would want
to do this, but it is arguably a restriction that implementors
don't need to place on users.</i>
</li>
<li> <i>Lifting the restrictions imposed in #2 and #3 above is possible
and simple, but would require more verbiage.</i>
</li>
</ol>
<p>Change 25.2.3/2 from:</p>
<blockquote>
-2- Requires: op and binary_op shall not have any side effects.
</blockquote>
<p>to:</p>
<blockquote>
-2- Requires: in the ranges [first1, last1], [first2, first2 +
(last1 - first1)] and [result, result + (last1- first1)], op and
binary_op shall neither modify elements nor invalidate iterators or
subranges.
[Footnote: The use of fully closed ranges is intentional --end footnote]
</blockquote>
<p>Change 25.2.3/2 from:</p>
<blockquote>
-2- Requires: op and binary_op shall not have any side effects.
</blockquote>
<p>to:</p>
<blockquote>
-2- Requires: op and binary_op shall not invalidate iterators or
subranges, or modify elements in the ranges [first1, last1],
[first2, first2 + (last1 - first1)], and [result, result + (last1
- first1)].
[Footnote: The use of fully closed ranges is intentional --end footnote]
</blockquote>
<p>Change 26.4.1/2 from:</p>
<blockquote>
-2- Requires: T must meet the requirements of CopyConstructible
(lib.copyconstructible) and Assignable (lib.container.requirements)
types. binary_op shall not cause side effects.
</blockquote>
<p>to:</p>
<blockquote>
-2- Requires: T must meet the requirements of CopyConstructible
(lib.copyconstructible) and Assignable
(lib.container.requirements) types. In the range [first, last],
binary_op shall neither modify elements nor invalidate iterators
or subranges.
[Footnote: The use of a fully closed range is intentional --end footnote]
</blockquote>
<p>Change 26.4.2/2 from:</p>
<blockquote>
-2- Requires: T must meet the requirements of CopyConstructible
(lib.copyconstructible) and Assignable (lib.container.requirements)
types. binary_op1 and binary_op2 shall not cause side effects.
</blockquote>
<p>to:</p>
<blockquote>
-2- Requires: T must meet the requirements of CopyConstructible
(lib.copyconstructible) and Assignable (lib.container.requirements)
types. In the ranges [first, last] and [first2, first2 + (last -
first)], binary_op1 and binary_op2 shall neither modify elements
nor invalidate iterators or subranges.
[Footnote: The use of fully closed ranges is intentional --end footnote]
</blockquote>
<p>Change 26.4.3/4 from:</p>
<blockquote>
-4- Requires: binary_op is expected not to have any side effects.
</blockquote>
<p>to:</p>
<blockquote>
-4- Requires: In the ranges [first, last] and [result, result +
(last - first)], binary_op shall neither modify elements nor
invalidate iterators or subranges.
[Footnote: The use of fully closed ranges is intentional --end footnote]
</blockquote>
<p>Change 26.4.4/2 from:</p>
<blockquote>
-2- Requires: binary_op shall not have any side effects.
</blockquote>
<p>to:</p>
<blockquote>
-2- Requires: In the ranges [first, last] and [result, result +
(last - first)], binary_op shall neither modify elements nor
invalidate iterators or subranges.
[Footnote: The use of fully closed ranges is intentional --end footnote]
</blockquote>
<p><i>[Toronto: Dave Abrahams supplied wording.]</i></p>
<p><i>[Copenhagen: Proposed resolution was modified slightly. Matt
added footnotes pointing out that the use of closed ranges was
intentional.]</i></p>
<hr>
<a name="247"><h3>247.&nbsp;<tt>vector</tt>, <tt>deque::insert</tt> complexity</h3></a><p>
<b>Section:</b>&nbsp;23.2.4.3 <a href="lib-containers.html#lib.vector.modifiers"> [lib.vector.modifiers]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Lisa Lippincott&nbsp; <b>Date:</b>&nbsp;06 June 2000</p>
<p>Paragraph 2 of 23.2.4.3 [lib.vector.modifiers] describes the complexity
of <tt>vector::insert</tt>:</p>
<blockquote>
Complexity: If first and last are forward iterators, bidirectional
iterators, or random access iterators, the complexity is linear in
the number of elements in the range [first, last) plus the distance
to the end of the vector. If they are input iterators, the complexity
is proportional to the number of elements in the range [first, last)
times the distance to the end of the vector.
</blockquote>
<p>First, this fails to address the non-iterator forms of
<tt>insert</tt>.</p>
<p>Second, the complexity for input iterators misses an edge case --
it requires that an arbitrary number of elements can be added at
the end of a <tt>vector</tt> in constant time.</p>
<p>At the risk of strengthening the requirement, I suggest simply</p>
<blockquote>
Complexity: The complexity is linear in the number of elements
inserted plus the distance to the end of the vector.
</blockquote>
<p>For input iterators, one may achieve this complexity by first
inserting at the end of the <tt>vector</tt>, and then using
<tt>rotate</tt>.</p>
<p>I looked to see if <tt>deque</tt> had a similar problem, and was
surprised to find that <tt>deque</tt> places no requirement on the
complexity of inserting multiple elements (23.2.1.3 ,
paragraph 3):</p>
<blockquote>
Complexity: In the worst case, inserting a single element into a
deque takes time linear in the minimum of the distance from the
insertion point to the beginning of the deque and the distance
from the insertion point to the end of the deque. Inserting a
single element either at the beginning or end of a deque always
takes constant time and causes a single call to the copy constructor
of T.
</blockquote>
<p>I suggest:</p>
<blockquote>
Complexity: The complexity is linear in the number of elements
inserted plus the shorter of the distances to the beginning and
end of the deque. Inserting a single element at either the
beginning or the end of a deque causes a single call to the copy
constructor of T.
</blockquote>
<p><b>Proposed resolution:</b></p>
<p><i>[Toronto: It's agreed that there is a defect in complexity of
multi-element insert for vector and deque. For vector, the complexity
should probably be something along the lines of <tt>c<sub>1</sub> * N
+ c<sub>2</sub> * distance(i, end())</tt>. However, there is some
concern about whether it is reasonable to amortize away the copies
that we get from a reallocation whenever we exceed the vector's
capacity. For deque, the situation is somewhat less clear. Deque is
notoriously complicated, and we may not want to impose complexity
requirements that would imply any implementation technique more
complicated than a while loop whose body is a single-element
insert.]</i></p>
<hr>
<a name="250"><h3>250.&nbsp;splicing invalidates iterators</h3></a><p>
<b>Section:</b>&nbsp;23.2.2.4 <a href="lib-containers.html#lib.list.ops"> [lib.list.ops]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Brian Parker &nbsp; <b>Date:</b>&nbsp;14 Jul 2000</p>
<p>
Section 23.2.2.4 [lib.list.ops] states that
</p>
<pre>
void splice(iterator position, list&lt;T, Allocator&gt;&amp; x);
</pre>
<p>
<i>invalidates</i> all iterators and references to list <tt>x</tt>.
</p>
<p>
This is unnecessary and defeats an important feature of splice. In
fact, the SGI STL guarantees that iterators to <tt>x</tt> remain valid
after <tt>splice</tt>.
</p>
<p><b>Proposed resolution:</b></p>
<p>Add a footnote to 23.2.2.4 , paragraph 1:</p>
<blockquote>
[<i>Footnote:</i> As specified in 20.1.5 , paragraphs
4-5, the semantics described in this clause applies only to the case
where allocators compare equal. --end footnote]
</blockquote>
<p>In 23.2.2.4 , replace paragraph 4 with:</p>
<blockquote>
Effects: Inserts the contents of x before position and x becomes
empty. Pointers and references to the moved elements of x now refer to
those same elements but as members of *this. Iterators referring to the
moved elements will continue to refer to their elements, but they now
behave as iterators into *this, not into x.
</blockquote>
<p>In 23.2.2.4 , replace paragraph 7 with:</p>
<blockquote>
Effects: Inserts an element pointed to by i from list x before
position and removes the element from x. The result is unchanged if
position == i or position == ++i. Pointers and references to *i continue
to refer to this same element but as a member of *this. Iterators to *i
(including i itself) continue to refer to the same element, but now
behave as iterators into *this, not into x.
</blockquote>
<p>In 23.2.2.4 , replace paragraph 12 with:</p>
<blockquote>
Requires: [first, last) is a valid range in x. The result is
undefined if position is an iterator in the range [first, last).
Pointers and references to the moved elements of x now refer to those
same elements but as members of *this. Iterators referring to the moved
elements will continue to refer to their elements, but they now behave as
iterators into *this, not into x.
</blockquote>
<p><i>[pre-Copenhagen: Howard provided wording.]</i></p>
<p><b>Rationale:</b></p>
<p>The original proposed resolution said that iterators and references
would remain &quot;valid&quot;. The new proposed resolution clarifies what that
means. Note that this only applies to the case of equal allocators.
From 20.1.5 paragraph 4, the behavior of list when
allocators compare nonequal is outside the scope of the standard.</p>
<hr>
<a name="253"><h3>253.&nbsp;valarray helper functions are almost entirely useless</h3></a><p>
<b>Section:</b>&nbsp;26.3.2.1 <a href="lib-numerics.html#lib.valarray.cons"> [lib.valarray.cons]</a>, 26.3.2.2 <a href="lib-numerics.html#lib.valarray.assign"> [lib.valarray.assign]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Robert Klarer&nbsp; <b>Date:</b>&nbsp;31 Jul 2000</p>
<p>This discussion is adapted from message c++std-lib-7056 posted
November 11, 1999. I don't think that anyone can reasonably claim
that the problem described below is NAD.</p>
<p>These valarray constructors can never be called:</p>
<pre>
template &lt;class T&gt;
valarray&lt;T&gt;::valarray(const slice_array&lt;T&gt; &amp;);
template &lt;class T&gt;
valarray&lt;T&gt;::valarray(const gslice_array&lt;T&gt; &amp;);
template &lt;class T&gt;
valarray&lt;T&gt;::valarray(const mask_array&lt;T&gt; &amp;);
template &lt;class T&gt;
valarray&lt;T&gt;::valarray(const indirect_array&lt;T&gt; &amp;);
</pre>
<p>Similarly, these valarray assignment operators cannot be
called:</p>
<pre>
template &lt;class T&gt;
valarray&lt;T&gt; valarray&lt;T&gt;::operator=(const slice_array&lt;T&gt; &amp;);
template &lt;class T&gt;
valarray&lt;T&gt; valarray&lt;T&gt;::operator=(const gslice_array&lt;T&gt; &amp;);
template &lt;class T&gt;
valarray&lt;T&gt; valarray&lt;T&gt;::operator=(const mask_array&lt;T&gt; &amp;);
template &lt;class T&gt;
valarray&lt;T&gt; valarray&lt;T&gt;::operator=(const indirect_array&lt;T&gt; &amp;);
</pre>
<p>Please consider the following example:</p>
<pre>
#include &lt;valarray&gt;
using namespace std;
int main()
{
valarray&lt;double&gt; va1(12);
valarray&lt;double&gt; va2(va1[slice(1,4,3)]); // line 1
}
</pre>
<p>Since the valarray va1 is non-const, the result of the sub-expression
va1[slice(1,4,3)] at line 1 is an rvalue of type const
std::slice_array&lt;double&gt;. This slice_array rvalue is then used to
construct va2. The constructor that is used to construct va2 is
declared like this:</p>
<pre>
template &lt;class T&gt;
valarray&lt;T&gt;::valarray(const slice_array&lt;T&gt; &amp;);
</pre>
<p>Notice the constructor's const reference parameter. When the
constructor is called, a slice_array must be bound to this reference.
The rules for binding an rvalue to a const reference are in 8.5.3,
paragraph 5 (see also 13.3.3.1.4). Specifically, paragraph 5
indicates that a second slice_array rvalue is constructed (in this
case copy-constructed) from the first one; it is this second rvalue
that is bound to the reference parameter. Paragraph 5 also requires
that the constructor that is used for this purpose be callable,
regardless of whether the second rvalue is elided. The
copy-constructor in this case is not callable, however, because it is
private. Therefore, the compiler should report an error.</p>
<p>Since slice_arrays are always rvalues, the valarray constructor that has a
parameter of type const slice_array&lt;T&gt; &amp; can never be called. The
same reasoning applies to the three other constructors and the four
assignment operators that are listed at the beginning of this post.
Furthermore, since these functions cannot be called, the valarray helper
classes are almost entirely useless.</p>
<p><b>Proposed resolution:</b></p>
<p>
Adopt section 2 of 00-0023/N1246. Sections 1 and 5 of that paper have
already been classified as &quot;Request for Extension&quot;. Sections
3 and 4 are reasonable generalizations of section 2, but they do not
resolve an obvious inconsistency in the standard.
</p>
<p><i>[Toronto: it is agreed that there is a defect. A full
discussion, and an attempt at fixing the defect, should wait until we
can hear from valarray experts.]</i></p>
<hr>
<a name="254"><h3>254.&nbsp;Exception types in clause 19 are constructed from <tt>std::string</tt>
</h3></a><p>
<b>Section:</b>&nbsp;19.1 <a href="lib-diagnostics.html#lib.std.exceptions"> [lib.std.exceptions]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Dave Abrahams&nbsp; <b>Date:</b>&nbsp;01 Aug 2000</p>
<p>
Many of the standard exception types which implementations are
required to throw are constructed with a const std::string&amp;
parameter. For example:
</p>
<pre>
19.1.5 Class out_of_range [lib.out.of.range]
namespace std {
class out_of_range : public logic_error {
public:
explicit out_of_range(const string&amp; what_arg);
};
}
1 The class out_of_range defines the type of objects thrown as excep-
tions to report an argument value not in its expected range.
out_of_range(const string&amp; what_arg);
Effects:
Constructs an object of class out_of_range.
Postcondition:
strcmp(what(), what_arg.c_str()) == 0.
</pre>
<p>
There are at least two problems with this:
</p>
<ol>
<li>A program which is low on memory may end up throwing
std::bad_alloc instead of out_of_range because memory runs out while
constructing the exception object.</li>
<li>An obvious implementation which stores a std::string data member
may end up invoking terminate() during exception unwinding because the
exception object allocates memory (or rather fails to) as it is being
copied.</li>
</ol>
<p>
There may be no cure for (1) other than changing the interface to
out_of_range, though one could reasonably argue that (1) is not a
defect. Personally I don't care that much if out-of-memory is reported
when I only have 20 bytes left, in the case when out_of_range would
have been reported. People who use exception-specifications might care
a lot, though.
</p>
<p>
There is a cure for (2), but it isn't completely obvious. I think a
note for implementors should be made in the standard. Avoiding
possible termination in this case shouldn't be left up to chance. The
cure is to use a reference-counted &quot;string&quot; implementation
in the exception object. I am not necessarily referring to a
std::string here; any simple reference-counting scheme for a NTBS
would do.
</p>
<p>
Further discussion, in email:
</p>
<p>
...I'm not so concerned about (1). After all, a library implementation
can add const char* constructors as an extension, and users don't
<i>need</i> to avail themselves of the standard exceptions, though this is
a lame position to be forced into. FWIW, std::exception and
std::bad_alloc don't require a temporary basic_string.
</p>
<p>
...I don't think the fixed-size buffer is a solution to the problem,
strictly speaking, because you can't satisfy the postcondition
<br>
<tt>&nbsp;&nbsp;strcmp(what(), what_arg.c_str()) == 0</tt>
<br>
For all values of what_arg (i.e. very long values). That means that
the only truly conforming solution requires a dynamic allocation.
</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Toronto: some LWG members thought this was merely a QoI issue,
but most believed that it was at least a borderline defect. There was
more support for nonnormative advice to implementors than for a
normative change.]</i></p>
<hr>
<a name="258"><h3>258.&nbsp;Missing allocator requirement</h3></a><p>
<b>Section:</b>&nbsp;20.1.5 <a href="lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;22 Aug 2000</p>
<p>
From lib-7752:
</p>
<p>
I've been assuming (and probably everyone else has been assuming) that
allocator instances have a particular property, and I don't think that
property can be deduced from anything in Table 32.
</p>
<p>
I think we have to assume that allocator type conversion is a
homomorphism. That is, if x1 and x2 are of type X, where
X::value_type is T, and if type Y is X::template
rebind&lt;U&gt;::other, then Y(x1) == Y(x2) if and only if x1 == x2.
</p>
<p>
Further discussion: Howard Hinnant writes, in lib-7757:
</p>
<p>
I think I can prove that this is not provable by Table 32. And I agree
it needs to be true except for the &quot;and only if&quot;. If x1 != x2, I see no
reason why it can't be true that Y(x1) == Y(x2). Admittedly I can't
think of a practical instance where this would happen, or be valuable.
But I also don't see a need to add that extra restriction. I think we
only need:
</p>
<blockquote>
if (x1 == x2) then Y(x1) == Y(x2)
</blockquote>
<p>
If we decide that == on allocators is transitive, then I think I can
prove the above. But I don't think == is necessarily transitive on
allocators. That is:
</p>
<p>
Given x1 == x2 and x2 == x3, this does not mean x1 == x3.
</p>
<p>Example:</p>
<blockquote>
<p>
x1 can deallocate pointers from: x1, x2, x3 <br>
x2 can deallocate pointers from: x1, x2, x4 <br>
x3 can deallocate pointers from: x1, x3 <br>
x4 can deallocate pointers from: x2, x4
</p>
<p>
x1 == x2, and x2 == x4, but x1 != x4
</p>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p><i>[Toronto: LWG members offered multiple opinions. One
opinion is that it should not be required that <tt>x1 == x2</tt>
implies <tt>Y(x1) == Y(x2)</tt>, and that it should not even be
required that <tt>X(x1) == x1</tt>. Another opinion is that
the second line from the bottom in table 32 already implies the
desired property. This issue should be considered in light of
other issues related to allocator instances.]</i></p>
<hr>
<a name="259"><h3>259.&nbsp;<tt>basic_string::operator[]</tt> and const correctness</h3></a><p>
<b>Section:</b>&nbsp;21.3.4 <a href="lib-strings.html#lib.string.access"> [lib.string.access]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Chris Newton &nbsp; <b>Date:</b>&nbsp;27 Aug 2000</p>
<p>
<i>Paraphrased from a message that Chris Newton posted to comp.std.c++:</i>
</p>
<p>
The standard's description of <tt>basic_string&lt;&gt;::operator[]</tt>
seems to violate const correctness.
</p>
<p>
The standard (21.3.4/1) says that &quot;If <tt>pos &lt; size()</tt>,
returns <tt>data()[pos]</tt>.&quot; The types don't work. The
return value of <tt>data()</tt> is <tt>const charT*</tt>, but
<tt>operator[]</tt> has a non-const version whose return type is <tt>reference</tt>.
</p>
<p><b>Proposed resolution:</b></p>
<p>
In section 21.3.4, paragraph 1, change
&quot;<tt>data()[<i>pos</i>]</tt>&quot; to &quot;<tt>*(begin() +
<i>pos</i>)</tt>&quot;.
</p>
<hr>
<a name="264"><h3>264.&nbsp;Associative container <tt>insert(i, j)</tt> complexity requirements are not feasible.</h3></a><p>
<b>Section:</b>&nbsp;23.1.2 <a href="lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;John Potter&nbsp; <b>Date:</b>&nbsp;07 Sep 2000</p>
<p>
Table 69 requires linear time if [i, j) is sorted. Sorted is necessary but not sufficient.
Consider inserting a sorted range of even integers into a set&lt;int&gt; containing the odd
integers in the same range.
</p>
<p><i>Related issue: <a href="lwg-closed.html#102">102</a></i></p>
<p><b>Proposed resolution:</b></p>
<p>
In Table 69, in section 23.1.2, change the complexity clause for
insertion of a range from &quot;N log(size() + N) (N is the distance
from i to j) in general; linear if [i, j) is sorted according to
value_comp()&quot; to &quot;N log(size() + N), where N is the distance
from i to j&quot;.
</p>
<p><i>[Copenhagen: Minor fix in proposed resolution: fixed unbalanced
parens in the revised wording.]</i></p>
<p><b>Rationale:</b></p>
<p>
Testing for valid insertions could be less efficient than simply
inserting the elements when the range is not both sorted and between
two adjacent existing elements; this could be a QOI issue.
</p>
<p>
The LWG considered two other options: (a) specifying that the
complexity was linear if [i, j) is sorted according to value_comp()
and between two adjacent existing elements; or (b) changing to
Klog(size() + N) + (N - K) (N is the distance from i to j and K is the
number of elements which do not insert immediately after the previous
element from [i, j) including the first). The LWG felt that, since
we can't guarantee linear time complexity whenever the range to be
inserted is sorted, it's more trouble than it's worth to say that it's
linear in some special cases.
</p>
<hr>
<a name="266"><h3>266.&nbsp;bad_exception::~bad_exception() missing Effects clause</h3></a><p>
<b>Section:</b>&nbsp;18.6.2.1 <a href="lib-support.html#lib.bad.exception"> [lib.bad.exception]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;24 Sep 2000</p>
<p>
The synopsis for std::bad_exception lists the function ~bad_exception()
but there is no description of what the function does (the Effects
clause is missing).
</p>
<p><b>Proposed resolution:</b></p>
<p>
Remove the destructor from the class synopses of
<tt>bad_alloc</tt> (18.4.2.1 ),
<tt>bad_cast</tt> (18.5.2 ),
<tt>bad_typeid</tt> (18.5.3 ),
and <tt>bad_exception</tt> (18.6.2.1 ).
</p>
<p><b>Rationale:</b></p>
<p>
This is a general problem with the exception classes in clause 18.
The proposed resolution is to remove the destructors from the class
synopses, rather than to document the destructors' behavior, because
removing them is more consistent with how exception classes are
described in clause 19.
</p>
<hr>
<a name="267"><h3>267.&nbsp;interaction of strstreambuf::overflow() and seekoff()</h3></a><p>
<b>Section:</b>&nbsp;D.7.1.3 <a href="future.html#depr.strstreambuf.virtuals"> [depr.strstreambuf.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;5 Oct 2000</p>
<p>
It appears that the interaction of the strstreambuf members overflow()
and seekoff() can lead to undefined behavior in cases where defined
behavior could reasonably be expected. The following program
demonstrates this behavior:
</p>
<pre>
#include &lt;strstream&gt;
int main ()
{
std::strstreambuf sb;
sb.sputc ('c');
sb.pubseekoff (-1, std::ios::end, std::ios::in);
return !('c' == sb.sgetc ());
}
</pre>
<p>
D.7.1.1, p1 initializes strstreambuf with a call to basic_streambuf&lt;&gt;(),
which in turn sets all pointers to 0 in 27.5.2.1, p1.
</p>
<p>
27.5.2.2.5, p1 says that basic_streambuf&lt;&gt;::sputc(c) calls
overflow(traits::to_int_type(c)) if a write position isn't available (it
isn't due to the above).
</p>
<p>
D.7.1.3, p3 says that strstreambuf::overflow(off, ..., ios::in) makes at
least one write position available (i.e., it allows the function to make
any positive number of write positions available).
</p>
<p>
D.7.1.3, p13 computes newoff = seekhigh - eback(). In D.7.1, p4 we see
seekhigh = epptr() ? epptr() : egptr(), or seekhigh = epptr() in this
case. newoff is then epptr() - eback().
</p>
<p>
D.7.1.4, p14 sets gptr() so that gptr() == eback() + newoff + off, or
gptr() == epptr() + off holds.
</p>
<p>
If strstreambuf::overflow() made exactly one write position available
then gptr() will be set to just before epptr(), and the program will
return 0. Buf if the function made more than one write position
available, epptr() and gptr() will both point past pptr() and the
behavior of the program is undefined.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the last sentence of D.7.1 paragraph 4 from</p>
<blockquote>
Otherwise, seeklow equals gbeg and seekhigh is either pend, if
pend is not a null pointer, or gend.
</blockquote>
<p>to become</p>
<blockquote>
Otherwise, seeklow equals gbeg and seekhigh is either gend if
0 == pptr(), or pbase() + max where max is the maximum value of
pptr() - pbase() ever reached for this stream.
</blockquote>
<p><i>[
pre-Copenhagen: Dietmar provided wording for proposed resolution.
]</i></p>
<p><i>[
post-Copenhagen: Fixed a typo: proposed resolution said to fix
4.7.1, not D.7.1.
]</i></p>
<p><b>Rationale:</b></p>
<p>Note that this proposed resolution does not require an increase in
the layout of strstreambuf to maintain max: If overflow() is
implemented to make exactly one write position available, max ==
epptr() - pbase() always holds. However, if overflow() makes more than
one write position available, the number of additional character (or
some equivalent) has to be stored somewhere.</p>
<hr>
<a name="270"><h3>270.&nbsp;Binary search requirements overly strict</h3></a><p>
<b>Section:</b>&nbsp;25.3.3 <a href="lib-algorithms.html#lib.alg.binary.search"> [lib.alg.binary.search]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;18 Oct 2000</p>
<p>
Each of the four binary search algorithms (lower_bound, upper_bound,
equal_range, binary_search) has a form that allows the user to pass a
comparison function object. According to 25.3, paragraph 2, that
comparison function object has to be a strict weak ordering.
</p>
<p>
This requirement is slightly too strict. Suppose we are searching
through a sequence containing objects of type X, where X is some
large record with an integer key. We might reasonably want to look
up a record by key, in which case we would want to write something
like this:
</p>
<pre>
struct key_comp {
bool operator()(const X&amp; x, int n) const {
return x.key() &lt; n;
}
}
std::lower_bound(first, last, 47, key_comp());
</pre>
<p>
key_comp is not a strict weak ordering, but there is no reason to
prohibit its use in lower_bound.
</p>
<p>
There's no difficulty in implementing lower_bound so that it allows
the use of something like key_comp. (It will probably work unless an
implementor takes special pains to forbid it.) What's difficult is
formulating language in the standard to specify what kind of
comparison function is acceptable. We need a notion that's slightly
more general than that of a strict weak ordering, one that can encompass
a comparison function that involves different types. Expressing that
notion may be complicated.
</p>
<p><i>Additional questions raised at the Toronto meeting:</i></p>
<ul>
<li> Do we really want to specify what ordering the implementor must
use when calling the function object? The standard gives
specific expressions when describing these algorithms, but it also
says that other expressions (with different argument order) are
equivalent.</li>
<li> If we are specifying ordering, note that the standard uses both
orderings when describing <tt>equal_range</tt>.</li>
<li> Are we talking about requiring these algorithms to work properly
when passed a binary function object whose two argument types
are not the same, or are we talking about requirements when
they are passed a binary function object with several overloaded
versions of <tt>operator()</tt>?</li>
<li> The definition of a strict weak ordering does not appear to give
any guidance on issues of overloading; it only discusses expressions,
and all of the values in these expressions are of the same type.
Some clarification would seem to be in order.</li>
</ul>
<p><i>Additional discussion from Copenhagen:</i></p>
<ul>
<li>It was generally agreed that there is a real defect here: if
the predicate is merely required to be a Strict Weak Ordering, then
it's possible to pass in a function object with an overloaded
operator(), where the version that's actually called does something
completely inappropriate. (Such as returning a random value.)</li>
<li>An alternative formulation was presented in a paper distributed by
David Abrahams at the meeting, &quot;Binary Search with Heterogeneous
Comparison&quot;, J16-01/0027 = WG21 N1313: Instead of viewing the
predicate as a Strict Weak Ordering acting on a sorted sequence, view
the predicate/value pair as something that partitions a sequence.
This is almost equivalent to saying that we should view binary search
as if we are given a unary predicate and a sequence, such that f(*p)
is true for all p below a specific point and false for all p above it.
The proposed resolution is based on that alternative formulation.</li>
</ul>
<p><b>Proposed resolution:</b></p>
<p>Change 25.3 [lib.alg.sorting] paragraph 3 from:</p>
<blockquote>
3 For all algorithms that take Compare, there is a version that uses
operator&lt; instead. That is, comp(*i, *j) != false defaults to *i &lt;
*j != false. For the algorithms to work correctly, comp has to
induce a strict weak ordering on the values.
</blockquote>
<p>to:</p>
<blockquote>
3 For all algorithms that take Compare, there is a version that uses
operator&lt; instead. That is, comp(*i, *j) != false defaults to *i &lt;
*j != false. For algorithms not described in lib.alg.binary.search
(25.3.3) to work correctly, comp has to induce a strict weak
ordering on the values.
</blockquote>
<p>Add the following paragraph after 25.3 [lib.alg.sorting] paragraph 5:</p>
<blockquote>
-6- A sequence [start, finish) is partitioned with respect to an
expression f(e) if there exists a non-negative integer n such that
for all 0 &lt;= i &lt; distance(start, finish), f(*(begin+i)) is true if
and only if i &lt; n.
</blockquote>
<p>Change 25.3.3 [lib.alg.binary.search] paragraph 1 from:</p>
<blockquote>
-1- All of the algorithms in this section are versions of binary
search and assume that the sequence being searched is in order
according to the implied or explicit comparison function. They work
on non-random access iterators minimizing the number of
comparisons, which will be logarithmic for all types of
iterators. They are especially appropriate for random access
iterators, because these algorithms do a logarithmic number of
steps through the data structure. For non-random access iterators
they execute a linear number of steps.
</blockquote>
<p>to:</p>
<blockquote>
-1- All of the algorithms in this section are versions of binary
search and assume that the sequence being searched is partitioned
with respect to an expression formed by binding the search key to
an argument of the implied or explicit comparison function. They
work on non-random access iterators minimizing the number of
comparisons, which will be logarithmic for all types of
iterators. They are especially appropriate for random access
iterators, because these algorithms do a logarithmic number of
steps through the data structure. For non-random access iterators
they execute a linear number of steps.
</blockquote>
<p>Change 25.3.3.1 [lib.lower.bound] paragraph 1 from:</p>
<blockquote>
-1- Requires: Type T is LessThanComparable
(lib.lessthancomparable).
</blockquote>
<p>to:</p>
<blockquote>
-1- Requires: The elements e of [first, last) are partitioned with
respect to the expression e &lt; value or comp(e, value)
</blockquote>
<p>Remove 25.3.3.1 [lib.lower.bound] paragraph 2:</p>
<blockquote>
-2- Effects: Finds the first position into which value can be
inserted without violating the ordering.
</blockquote>
<p>Change 25.3.3.2 [lib.upper.bound] paragraph 1 from:</p>
<blockquote>
-1- Requires: Type T is LessThanComparable (lib.lessthancomparable).
</blockquote>
<p>to:</p>
<blockquote>
-1- Requires: The elements e of [first, last) are partitioned with
respect to the expression !(value &lt; e) or !comp(value, e)
</blockquote>
<p>Remove 25.3.3.2 [lib.upper.bound] paragraph 2:</p>
<blockquote>
-2- Effects: Finds the furthermost position into which value can be
inserted without violating the ordering.
</blockquote>
<p>Change 25.3.3.3 [lib.equal.range] paragraph 1 from:</p>
<blockquote>
-1- Requires: Type T is LessThanComparable
(lib.lessthancomparable).
</blockquote>
<p>to:</p>
<blockquote>
-1- Requires: The elements e of [first, last) are partitioned with
respect to the expressions e &lt; value and !(value &lt; e) or
comp(e, value) and !comp(value, e).
</blockquote>
<p>
Optionally add the following to the end of the proposed text above,
which allows library implementors to make a small optimization at the
cost of slightly complexifying the standard text. The idea is that we
want to ensure that the partition point which defines the upper_bound
is no earlier in the sequence than the partion point which defines the
lower_bound, so that the implementor can do one of the searches over a
subrange:
</p>
<blockquote>
Also, for all elements e of [first, last), e &lt; value implies
!(value &lt; e) or comp(e, value) implies !comp(value, e)
</blockquote>
<p>Note also that if we don't add the above, the result of
equal_range() might be an invalid range.</p>
<p>Change 25.3.3.3 [lib.equal.range] paragraph 2 from:</p>
<blockquote>
-2- Effects: Finds the largest subrange [i, j) such that the value
can be inserted at any iterator k in it without violating the
ordering. k satisfies the corresponding conditions: !(*k &lt; value)
&amp;&amp; !(value &lt; *k) or comp(*k, value) == false &amp;&amp; comp(value, *k) ==
false.
</blockquote>
<p>to:</p>
<pre>
-2- Returns:
make_pair(lower_bound(first, last, value),
upper_bound(first, last, value))
or
make_pair(lower_bound(first, last, value, comp),
upper_bound(first, last, value, comp))
</pre>
<p>
Note that the original text did not say whether the first element of
the return value was the beginning or end of the range, or something
else altogether. The proposed text is both more precise and general
enough to accomodate heterogeneous comparisons.
</p>
<p>Change 25.3.3.3 [lib.binary.search] paragraph 1 from:</p>
<blockquote>
-1- Requires: Type T is LessThanComparable
(lib.lessthancomparable).
</blockquote>
<p>to:</p>
<blockquote>
-1- Requires: The elements e of [first, last) are partitioned with
respect to the expressions e &lt; value and !(value &lt; e) or comp(e,
value) and !comp(value, e). Also, for all elements e of [first,
last), e &lt; value implies !(value &lt; e) or comp(e, value) implies
!comp(value, e)
</blockquote>
<p><i>[Dave Abrahams provided this wording]</i></p>
<hr>
<a name="271"><h3>271.&nbsp;basic_iostream missing typedefs</h3></a><p>
<b>Section:</b>&nbsp;27.6.1.5 <a href="lib-iostreams.html#lib.iostreamclass"> [lib.iostreamclass]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;02 Nov 2000</p>
<p>
Class template basic_iostream has no typedefs. The typedefs it
inherits from its base classes can't be used, since (for example)
basic_iostream&lt;T&gt;::traits_type is ambiguous.
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following to basic_iostream's class synopsis in
27.6.1.5 , immediately after <tt>public</tt>:</p>
<pre>
// types:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
</pre>
<hr>
<a name="272"><h3>272.&nbsp;Missing parentheses around subexpression</h3></a><p>
<b>Section:</b>&nbsp;27.4.4.3 <a href="lib-iostreams.html#lib.iostate.flags"> [lib.iostate.flags]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;02 Nov 2000</p>
<p>
27.4.4.3, p4 says about the postcondition of the function: If
rdbuf()!=0 then state == rdstate(); otherwise
rdstate()==state|ios_base::badbit.
</p>
<p>
The expression on the right-hand-side of the operator==() needs to be
parenthesized in order for the whole expression to ever evaluate to
anything but non-zero.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Add parentheses like so: rdstate()==(state|ios_base::badbit).
</p>
<hr>
<a name="273"><h3>273.&nbsp;Missing ios_base qualification on members of a dependent class</h3></a><p>
<b>Section:</b>&nbsp;27 <a href="lib-iostreams.html#lib.input.output"> [lib.input.output]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;02 Nov 2000</p>
<p>27.5.2.4.2, p4, and 27.8.1.6, p2, 27.8.1.7, p3, 27.8.1.9, p2,
27.8.1.10, p3 refer to in and/or out w/o ios_base:: qualification.
That's incorrect since the names are members of a dependent base
class (14.6.2 [temp.dep]) and thus not visible.</p>
<p><b>Proposed resolution:</b></p>
<p>Qualify the names with the name of the class of which they are
members, i.e., ios_base.</p>
<hr>
<a name="274"><h3>274.&nbsp;a missing/impossible allocator requirement</h3></a><p>
<b>Section:</b>&nbsp;20.1.5 <a href="lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;02 Nov 2000</p>
<p>
I see that table 31 in 20.1.5, p3 allows T in std::allocator&lt;T&gt; to be of
any type. But the synopsis in 20.4.1 calls for allocator&lt;&gt;::address() to
be overloaded on reference and const_reference, which is ill-formed for
all T = const U. In other words, this won't work:
</p>
<p>
template class std::allocator&lt;const int&gt;;
</p>
<p>
The obvious solution is to disallow specializations of allocators on
const types. However, while containers' elements are required to be
assignable (which rules out specializations on const T's), I think that
allocators might perhaps be potentially useful for const values in other
contexts. So if allocators are to allow const types a partial
specialization of std::allocator&lt;const T&gt; would probably have to be
provided.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the text in row 1, column 2 of table 32 in 20.1.5, p3 from</p>
<blockquote>
any type
</blockquote>
<p>to</p>
<blockquote>
any non-const, non-volatile, non-reference type
</blockquote>
<p><b>Rationale:</b></p>
<p>
Two resolutions were originally proposed: one that partially
specialized std::allocator for const types, and one that said an
allocator's value type may not be const. The LWG chose the second.
The first wouldn't be appropriate, because allocators are intended for
use by containers, and const value types don't work in containers.
Encouraging the use of allocators with const value types would only
lead to unsafe code.
</p>
<p>
The original text for proposed resolution 2 was modified so that it
also forbids volatile types and reference types.
</p>
<hr>
<a name="275"><h3>275.&nbsp;Wrong type in num_get::get() overloads</h3></a><p>
<b>Section:</b>&nbsp;22.2.2.1.1 <a href="lib-locales.html#lib.facet.num.get.members"> [lib.facet.num.get.members]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;02 Nov 2000</p>
<p>
In 22.2.2.1.1, we have a list of overloads for num_get&lt;&gt;::get().
There are eight overloads, all of which are identical except for the
last parameter. The overloads are:
</p>
<ul>
<li> long&amp; </li>
<li> unsigned short&amp; </li>
<li> unsigned int&amp; </li>
<li> unsigned long&amp; </li>
<li> short&amp; </li>
<li> double&amp; </li>
<li> long double&amp; </li>
<li> void*&amp; </li>
</ul>
<p>
There is a similar list, in 22.2.2.1.2, of overloads for
num_get&lt;&gt;::do_get(). In this list, the last parameter has
the types:
</p>
<ul>
<li> long&amp; </li>
<li> unsigned short&amp; </li>
<li> unsigned int&amp; </li>
<li> unsigned long&amp; </li>
<li> float&amp; </li>
<li> double&amp; </li>
<li> long double&amp; </li>
<li> void*&amp; </li>
</ul>
<p>
These two lists are not identical. They should be, since
<tt>get</tt> is supposed to call <tt>do_get</tt> with exactly
the arguments it was given.
</p>
<p><b>Proposed resolution:</b></p>
<p>In 22.2.2.1.1 , change</p>
<pre>
iter_type get(iter_type in, iter_type end, ios_base&amp; str,
ios_base::iostate&amp; err, short&amp; val) const;
</pre>
<p>to</p>
<pre>
iter_type get(iter_type in, iter_type end, ios_base&amp; str,
ios_base::iostate&amp; err, float&amp; val) const;
</pre>
<hr>
<a name="276"><h3>276.&nbsp;Assignable requirement for container value type overly strict</h3></a><p>
<b>Section:</b>&nbsp;23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Peter Dimov&nbsp; <b>Date:</b>&nbsp;07 Nov 2000</p>
<p>
23.1/3 states that the objects stored in a container must be
Assignable. 23.3.1 , paragraph 2,
states that map satisfies all requirements for a container, while in
the same time defining value_type as pair&lt;const Key, T&gt; - a type
that is not Assignable.
</p>
<p>
It should be noted that there exists a valid and non-contradictory
interpretation of the current text. The wording in 23.1/3 avoids
mentioning value_type, referring instead to &quot;objects stored in a
container.&quot; One might argue that map does not store objects of
type map::value_type, but of map::mapped_type instead, and that the
Assignable requirement applies to map::mapped_type, not
map::value_type.
</p>
<p>
However, this makes map a special case (other containers store objects of
type value_type) and the Assignable requirement is needlessly restrictive in
general.
</p>
<p>
For example, the proposed resolution of active library issue
<a href="lwg-defects.html#103">103</a> is to make set::iterator a constant iterator; this
means that no set operations can exploit the fact that the stored
objects are Assignable.
</p>
<p>
This is related to, but slightly broader than, closed issue
<a href="lwg-closed.html#140">140</a>.
</p>
<p><b>Proposed resolution:</b></p>
<p>23.1/3: Strike the trailing part of the sentence:</p>
<blockquote>
, and the additional requirements of Assignable types from 23.1/3
</blockquote>
<p>so that it reads:</p>
<blockquote>
-3- The type of objects stored in these components must meet the
requirements of CopyConstructible types (lib.copyconstructible).
</blockquote>
<p>23.1/4: Modify to make clear that this requirement is not for all
containers. Change to:</p>
<blockquote>
-4- Table 64 defines the Assignable requirement. Some containers
require this property of the types to be stored in the container. T is
the type used to instantiate the container. t is a value of T, and u is
a value of (possibly const) T.
</blockquote>
<p>23.1, Table 65: in the first row, change &quot;T is Assignable&quot; to &quot;T is
CopyConstructible&quot;.</p>
<p>23.2.1/2: Add sentence for Assignable requirement. Change to:</p>
<blockquote>
-2- A deque satisfies all of the requirements of a container and of a
reversible container (given in tables in lib.container.requirements) and
of a sequence, including the optional sequence requirements
(lib.sequence.reqmts). In addition to the requirements on the stored
object described in 23.1[lib.container.requirements], the stored object
must also meet the requirements of Assignable. Descriptions are
provided here only for operations on deque that are not described in one
of these tables or for operations where there is additional semantic
information.
</blockquote>
<p>23.2.2/2: Add Assignable requirement to specific methods of list.
Change to:</p>
<blockquote>
<p>-2- A list satisfies all of the requirements of a container and of a
reversible container (given in two tables in lib.container.requirements)
and of a sequence, including most of the the optional sequence
requirements (lib.sequence.reqmts). The exceptions are the operator[]
and at member functions, which are not provided.
[Footnote: These member functions are only provided by containers whose
iterators are random access iterators. --- end foonote]
</p>
<p>list does not require the stored type T to be Assignable unless the
following methods are instantiated:
[Footnote: Implementors are permitted but not required to take advantage
of T's Assignable properties for these methods. -- end foonote]
</p>
<pre>
list&lt;T,Allocator&gt;&amp; operator=(const list&lt;T,Allocator&gt;&amp; x );
template &lt;class InputIterator&gt;
void assign(InputIterator first, InputIterator last);
void assign(size_type n, const T&amp; t);
</pre>
<p>Descriptions are provided here only for operations on list that are not
described in one of these tables or for operations where there is
additional semantic information.</p>
</blockquote>
<p>23.2.4/2: Add sentence for Assignable requirement. Change to:</p>
<blockquote>
-2- A vector satisfies all of the requirements of a container and of a
reversible container (given in two tables in lib.container.requirements)
and of a sequence, including most of the optional sequence requirements
(lib.sequence.reqmts). The exceptions are the push_front and pop_front
member functions, which are not provided. In addition to the
requirements on the stored object described in
23.1[lib.container.requirements], the stored object must also meet the
requirements of Assignable. Descriptions are provided here only for
operations on vector that are not described in one of these tables or
for operations where there is additional semantic information.
</blockquote>
<p><b>Rationale:</b></p>
<p>list, set, multiset, map, multimap are able to store non-Assignables.
However, there is some concern about <tt>list&lt;T&gt;</tt>:
although in general there's no reason for T to be Assignable, some
implementations of the member functions <tt>operator=</tt> and
<tt>assign</tt> do rely on that requirement. The LWG does not want
to forbid such implementations.</p>
<p>Note that the type stored in a standard container must still satisfy
the requirements of the container's allocator; this rules out, for
example, such types as &quot;const int&quot;. See issue <a href="lwg-active.html#274">274</a>
for more details.
</p>
<hr>
<a name="278"><h3>278.&nbsp;What does iterator validity mean?</h3></a><p>
<b>Section:</b>&nbsp;23.2.2.4 <a href="lib-containers.html#lib.list.ops"> [lib.list.ops]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;P.J. Plauger&nbsp; <b>Date:</b>&nbsp;27 Nov 2000</p>
<p>
Section 23.2.2.4 [lib.list.ops] states that
</p>
<pre>
void splice(iterator position, list&lt;T, Allocator&gt;&amp; x);
</pre>
<p>
<i>invalidates</i> all iterators and references to list <tt>x</tt>.
</p>
<p>
But what does the C++ Standard mean by &quot;invalidate&quot;? You
can still dereference the iterator to a spliced list element, but
you'd better not use it to delimit a range within the original
list. For the latter operation, it has definitely lost some of its
validity.
</p>
<p>
If we accept the proposed resolution to issue <a href="lwg-active.html#250">250</a>,
then we'd better clarify that a &quot;valid&quot; iterator need no
longer designate an element within the same container as it once did.
We then have to clarify what we mean by invalidating a past-the-end
iterator, as when a vector or string grows by reallocation. Clearly,
such an iterator has a different kind of validity. Perhaps we should
introduce separate terms for the two kinds of &quot;validity.&quot;
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following text to the end of section 24.1 ,
after paragraph 5:</p>
<blockquote>
<i>Invalidating</i> an iterator means modifying it such that
it may have a singular value. [Footnote: This definition applies to
pointers, since pointers are iterators. The effect of dereferencing
an iterator that has been invalidated is undefined.]
</blockquote>
<p><i>[post-Copenhagen: Matt provided wording.]</i></p>
<hr>
<a name="280"><h3>280.&nbsp;Comparison of reverse_iterator to const reverse_iterator</h3></a><p>
<b>Section:</b>&nbsp;24.4.1 <a href="lib-iterators.html#lib.reverse.iterators"> [lib.reverse.iterators]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Steve Cleary&nbsp; <b>Date:</b>&nbsp;27 Nov 2000</p>
<p>
This came from an email from Steve Cleary to Fergus in reference to
issue <a href="lwg-active.html#179">179</a>. The library working group briefly discussed
this in Toronto and believed it should be a separate issue. There was
also some reservations about whether this was a worthwhile problem to
fix.
</p>
<p>
Steve said: &quot;Fixing reverse_iterator. std::reverse_iterator can
(and should) be changed to preserve these additional
requirements.&quot; He also said in email that it can be done without
breaking user's code: &quot;If you take a look at my suggested
solution, reverse_iterator doesn't have to take two parameters; there
is no danger of breaking existing code, except someone taking the
address of one of the reverse_iterator global operator functions, and
I have to doubt if anyone has ever done that. . . <i>But</i>, just in
case they have, you can leave the old global functions in as well --
they won't interfere with the two-template-argument functions. With
that, I don't see how <i>any</i> user code could break.&quot;
</p>
<p><b>Proposed resolution:</b></p>
<p>
<b>Section:</b> 24.4.1.1
add/change the following declarations:</p>
<pre>
A) Add a templated assignment operator, after the same manner
as the templated copy constructor, i.e.:
template &lt; class U &gt;
reverse_iterator &lt; Iterator &gt;&amp; operator=(const reverse_iterator&lt; U &gt;&amp; u);
B) Make all global functions (except the operator+) have
two template parameters instead of one, that is, for
operator ==, !=, &lt;, &gt;, &lt;=, &gt;=, - replace:
template &lt; class Iterator &gt;
typename reverse_iterator&lt; Iterator &gt;::difference_type operator-(
const reverse_iterator&lt; Iterator &gt;&amp; x,
const reverse_iterator&lt; Iterator &gt;&amp; y);
with:
template &lt; class Iterator1, class Iterator2 &gt;
typename reverse_iterator &lt; Iterator1 &gt;::difference_type operator-(
const reverse_iterator &lt; Iterator1 &gt; &amp; x,
const reverse_iterator &lt; Iterator2 &gt; &amp; y);
</pre>
<p>
Also make the addition/changes for these signatures in
24.4.1.3 .
</p>
<p><i>[
Copenhagen: The LWG is concerned that the proposed resolution
introduces new overloads. Experience shows that introducing
overloads is always risky, and that it would be inappropriate to
make this change without implementation experience. It may be
desirable to provide this feature in a different way.
]</i></p>
<hr>
<a name="281"><h3>281.&nbsp;std::min() and max() requirements overly restrictive</h3></a><p>
<b>Section:</b>&nbsp;25.3.7 <a href="lib-algorithms.html#lib.alg.min.max"> [lib.alg.min.max]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;02 Dec 2000</p>
<p>The requirements in 25.3.7, p1 and 4 call for T to satisfy the
requirements of <tt>LessThanComparable</tt> (20.1.2 )
and <tt>CopyConstructible</tt> (20.1.3 ).
Since the functions take and return their arguments and result by
const reference, I believe the <tt>CopyConstructible</tt> requirement
is unnecessary.
</p>
<p><b>Proposed resolution:</b></p>
<p>Remove the <tt>CopyConstructible</tt> requirement. Specifically, replace
25.3.7, p1 with</p>
<p>
<b>-1- Requires:</b> Type T is <tt>LessThanComparable</tt>
(20.1.2 ).
</p>
<p>and replace 25.3.7, p4 with</p>
<p>
<b>-4- Requires:</b> Type T is <tt>LessThanComparable</tt>
(20.1.2 ).
</p>
<hr>
<a name="282"><h3>282.&nbsp;What types does numpunct grouping refer to?</h3></a><p>
<b>Section:</b>&nbsp;22.2.2.2.2 <a href="lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Howard Hinnant&nbsp; <b>Date:</b>&nbsp;5 Dec 2000</p>
<p>
Paragraph 16 mistakenly singles out integral types for inserting
thousands_sep() characters. This conflicts with the syntax for floating
point numbers described under 22.2.3.1/2.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change paragraph 16 from:</p>
<blockquote>
For integral types, punct.thousands_sep() characters are inserted into
the sequence as determined by the value returned by punct.do_grouping()
using the method described in 22.2.3.1.2 .
</blockquote>
<p>To:</p>
<blockquote>
For arithmetic types, punct.thousands_sep() characters are inserted into
the sequence as determined by the value returned by punct.do_grouping()
using the method described in 22.2.3.1.2 .
</blockquote>
<p><i>[
Copenhagen: Opinions were divided about whether this is actually an
inconsistency, but at best it seems to have been unintentional. This
is only an issue for floating-point output: The standard is
unambiguous that implementations must parse thousands_sep characters
when performing floating-point. The standard is also unambiguous that
this requirement does not apply to the &quot;C&quot; locale.
]</i></p>
<p><i>[
A survey of existing practice is needed; it is believed that some
implementations do insert thousands_sep characters for floating-point
output and others doing.
]</i></p>
<hr>
<a name="283"><h3>283.&nbsp;std::replace() requirement incorrect/insufficient</h3></a><p>
<b>Section:</b>&nbsp;25.2.4 <a href="lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;15 Dec 2000</p>
<p>
The requirements in 25.2.4 , p1 that <tt>T</tt> to be
<tt>Assignable</tt> (23.1 ) is not necessary or
sufficient for either of the algorithms. The algorithms require that
<tt>std::iterator_traits&lt;ForwardIterator&gt;::value_type</tt> be
<tt>Assignable</tt> and that both
<tt>std::iterator_traits&lt;ForwardIterator&gt;::value_type</tt> and be
<tt>EqualityComparable</tt> (20.1.1 ) with respect to
one another.
</p>
<p>
Note that a similar problem occurs in several other places in section
25 as well (e.g., 25.1.6 , or 25.2.5 ) so
what really needs to happen is for all those places to be identified
and corrected. The proposed resolution below addresses only 25.2.4.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 25.2.4, p1 from</p>
<blockquote>
<b>-1- Requires:</b>Type <tt>T</tt> is <tt>Assignable</tt>
(23.1 ) (and, for <tt>replace()</tt>,
<tt>EqualityComparable</tt> (20.1.1 )).
</blockquote>
<p>to</p>
<blockquote>
<b>-1- Requires:</b>Type
<tt>std::iterator_traits&lt;ForwardIterator&gt;::value_type</tt>
is <tt>Assignable</tt> (23.1 ), the type <tt>T</tt> is
convertible to<tt>std::iterator_traits&lt;ForwardIterator&gt;::value_type</tt>,
(and, for <tt>replace()</tt>, types
<tt>std::iterator_traits&lt;ForwardIterator&gt;::value_type</tt> and
<tt>T</tt> are <tt>EqualityComparable</tt> (20.1.1 )
with respect to one another).
</blockquote>
<p><i>[
The LWG agrees with the general idea of the proposed resolution, but
not with the specific wording. (There is no definition in the
standard of what it means for one type to be EqualityComparable to
another.) Jeremy will provide new wording, and will review clause 25
for similar issues.
]</i></p>
<hr>
<a name="284"><h3>284.&nbsp;unportable example in 20.3.7, p6</h3></a><p>
<b>Section:</b>&nbsp;20.3.7 <a href="lib-utilities.html#lib.function.pointer.adaptors"> [lib.function.pointer.adaptors]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;26 Dec 2000</p>
<p>The example in 20.3.7 , p6 shows how to use the C
library function <tt>strcmp()</tt> with the function pointer adapter
<tt>ptr_fun()</tt>. But since it's unspecified whether the C library
functions have <tt>extern &quot;C&quot;</tt> or <tt>extern
&quot;C++&quot;</tt> linkage [17.4.2.2 ], and since
function pointers with different the language linkage specifications
(7.5 ) are incompatible, whether this example is
well-formed is unspecified.
</p>
<p><b>Proposed resolution:</b></p>
<p>Replace the code snippet in the following text</p>
<blockquote>
<p>
<b>-6- </b>[<i>Example:</i>
</p>
<pre>
replace_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(strcmp), &quot;C&quot;)), &quot;C++&quot;);
</pre>
</blockquote>
<p>with</p>
<blockquote>
<p>
<b>-6- </b>[<i>Example:</i>
</p>
<pre>
int compare(const char*, const char*);
replace_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(compare), &quot;abc&quot;)), &quot;def&quot;);
</pre>
</blockquote>
<p><i>[Copenhagen: Minor change in the proposed resolution. Since this
issue deals in part with C and C++ linkage, it was believed to be too
confusing for the strings in the example to be &quot;C&quot; and &quot;C++&quot;.
]</i></p>
<hr>
<a name="285"><h3>285.&nbsp;minor editorial errors in fstream ctors</h3></a><p>
<b>Section:</b>&nbsp;27.8.1.6 <a href="lib-iostreams.html#lib.ifstream.cons"> [lib.ifstream.cons]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;31 Dec 2000</p>
<p>27.8.1.6 , p2, 27.8.1.9 , p2, and
27.8.1.12 , p2 say about the effects of each constructor:
<a href="lib-iostreams.html#lib.ifstream.cons"> [lib.ifstream.cons]</a>
</p>
<p>... If that function returns a null pointer, calls
<tt>setstate(failbit)</tt> (which may throw <tt>ios_base::failure</tt>).
</p>
<p>The parenthetical note doesn't apply since the ctors cannot throw an
exception due to the requirement in 27.4.4.1 , p3
that <tt>exceptions()</tt> be initialized to <tt>ios_base::goodbit</tt>.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Strike the parenthetical note from the Effects clause in each of the
paragraphs mentioned above.
</p>
<hr>
<a name="286"><h3>286.&nbsp;&lt;cstdlib&gt; requirements missing size_t typedef</h3></a><p>
<b>Section:</b>&nbsp;25.4 <a href="lib-algorithms.html#lib.alg.c.library"> [lib.alg.c.library]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Judy Ward&nbsp; <b>Date:</b>&nbsp;30 Dec 2000</p>
<p>
The &lt;cstdlib&gt; header file contains prototypes for bsearch and
qsort (C++ Standard section 25.4 paragraphs 3 and 4) and other
prototypes (C++ Standard section 21.4 paragraph 1 table 49) that
require the typedef size_t. Yet size_t is not listed in the
&lt;cstdlib&gt; synopsis table 78 in section 25.4.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Add the type size_t to Table 78 (section 25.4) and add
the type size_t &lt;cstdlib&gt; to Table 97 (section C.2).
</p>
<p><b>Rationale:</b></p>
<p>Since size_t is in &lt;stdlib.h&gt;, it must also be in &lt;cstdlib&gt;.</p>
<hr>
<a name="288"><h3>288.&nbsp;&lt;cerrno&gt; requirements missing macro EILSEQ</h3></a><p>
<b>Section:</b>&nbsp;19.3 <a href="lib-diagnostics.html#lib.errno"> [lib.errno]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Judy Ward&nbsp; <b>Date:</b>&nbsp;30 Dec 2000</p>
<p>
ISO/IEC 9899:1990/Amendment1:1994 Section 4.3 States: &quot;The list
of macros defined in &lt;errno.h&gt; is adjusted to include a new
macro, EILSEQ&quot;
</p>
<p>
ISO/IEC 14882:1998(E) section 19.3 does not refer
to the above amendment.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Update Table 26 (section 19.3) &quot;Header &lt;cerrno&gt; synopsis&quot;
and Table 95 (section C.2) &quot;Standard Macros&quot; to include EILSEQ.
</p>
<hr>
<a name="290"><h3>290.&nbsp;Requirements to for_each and its function object</h3></a><p>
<b>Section:</b>&nbsp;25.1.1 <a href="lib-algorithms.html#lib.alg.foreach"> [lib.alg.foreach]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Angelika Langer&nbsp; <b>Date:</b>&nbsp;03 Jan 2001</p>
<p>The specification of the for_each algorithm does not have a
&quot;Requires&quot; section, which means that there are no
restrictions imposed on the function object whatsoever. In essence it
means that I can provide any function object with arbitrary side
effects and I can still expect a predictable result. In particular I
can expect that the function object is applied exactly last - first
times, which is promised in the &quot;Complexity&quot; section.
</p>
<p>I don't see how any implementation can give such a guarantee
without imposing requirements on the function object.
</p>
<p>Just as an example: consider a function object that removes
elements from the input sequence. In that case, what does the
complexity guarantee (applies f exactly last - first times) mean?
</p>
<p>One can argue that this is obviously a nonsensical application and
a theoretical case, which unfortunately it isn't. I have seen
programmers shooting themselves in the foot this way, and they did not
understand that there are restrictions even if the description of the
algorithm does not say so.
</p>
<p><b>Proposed resolution:</b></p>
<p>Add a &quot;Requires&quot; section to section 25.1.1 similar to those
proposed for transform and the numeric algorithms (see issue
<a href="lwg-active.html#242">242</a>):
</p>
<blockquote>
-2- <b>Requires</b>: In the range [first, last], f shall not invalidate
iterators or subranges.
</blockquote>
<p><i>[Copenhagen: The LWG agrees that a function object passed to an
algorithm should not invalidate iterators in the range that the
algorithm is operating on. The LWG believes that this should be a
blanket statement in Clause 25, not just a special requirement for
<tt>for_each</tt>.
]</i></p>
<hr>
<a name="291"><h3>291.&nbsp;Underspecification of set algorithms</h3></a><p>
<b>Section:</b>&nbsp;25.3.5 <a href="lib-algorithms.html#lib.alg.set.operations"> [lib.alg.set.operations]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;03 Jan 2001</p>
<p>
The standard library contains four algorithms that compute set
operations on sorted ranges: <tt>set_union</tt>, <tt>set_intersection</tt>,
<tt>set_difference</tt>, and <tt>set_symmetric_difference</tt>. Each
of these algorithms takes two sorted ranges as inputs, and writes the
output of the appropriate set operation to an output range. The elements
in the output range are sorted.
</p>
<p>
The ordinary mathematical definitions are generalized so that they
apply to ranges containing multiple copies of a given element. Two
elements are considered to be &quot;the same&quot; if, according to an
ordering relation provided by the user, neither one is less than the
other. So, for example, if one input range contains five copies of an
element and another contains three, the output range of <tt>set_union</tt>
will contain five copies, the output range of
<tt>set_intersection</tt> will contain three, the output range of
<tt>set_difference</tt> will contain two, and the output range of
<tt>set_symmetric_difference</tt> will contain two.
</p>
<p>
Because two elements can be &quot;the same&quot; for the purposes
of these set algorithms, without being identical in other respects
(consider, for example, strings under case-insensitive comparison),
this raises a number of unanswered questions:
</p>
<ul>
<li>If we're copying an element that's present in both of the
input ranges, which one do we copy it from?</li>
<li>If there are <i>n</i> copies of an element in the relevant
input range, and the output range will contain fewer copies (say
<i>m</i>) which ones do we choose? The first <i>m</i>, or the last
<i>m</i>, or something else?</li>
<li>Are these operations stable? That is, does a run of equivalent
elements appear in the output range in the same order as as it
appeared in the input range(s)?</li>
</ul>
<p>
The standard should either answer these questions, or explicitly
say that the answers are unspecified. I prefer the former option,
since, as far as I know, all existing implementations behave the
same way.
</p>
<p><b>Proposed resolution:</b></p>
<p><i>[The LWG agrees that the standard should answer these questions.
Matt will provide wording.]</i></p>
<hr>
<a name="292"><h3>292.&nbsp;effects of a.copyfmt (a)</h3></a><p>
<b>Section:</b>&nbsp;27.4.4.2 <a href="lib-iostreams.html#lib.basic.ios.members"> [lib.basic.ios.members]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;05 Jan 2001</p>
<p>The Effects clause of the member function <tt>copyfmt()</tt> in
27.4.4.2, p15 doesn't consider the case where the left-hand side
argument is identical to the argument on the right-hand side, that is
<tt>(this == &amp;rhs)</tt>. If the two arguments are identical there
is no need to copy any of the data members or call any callbacks
registered with <tt>register_callback()</tt>. Also, as Howard Hinnant
points out in message c++std-lib-8149 it appears to be incorrect to
allow the object to fire <tt>erase_event</tt> followed by
<tt>copyfmt_event</tt> since the callback handling the latter event
may inadvertently attempt to access memory freed by the former.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the Effects clause in 27.4.4.2, p15 from</p>
<blockquote>
<b>-15- Effects:</b>Assigns to the member objects of <tt>*this</tt>
the corresponding member objects of <tt>rhs</tt>, except that...
</blockquote>
<p>to</p>
<blockquote>
<b>-15- Effects:</b>If <tt>(this == &amp;rhs)</tt> does nothing. Otherwise
assigns to the member objects of <tt>*this</tt> the corresponding member
objects of <tt>rhs</tt>, except that...
</blockquote>
<hr>
<a name="294"><h3>294.&nbsp;User defined macros and standard headers</h3></a><p>
<b>Section:</b>&nbsp;17.4.3.1.1 <a href="lib-intro.html#lib.macro.names"> [lib.macro.names]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;James Kanze&nbsp; <b>Date:</b>&nbsp;11 Jan 2001</p>
<p>Paragraph 2 of 17.4.3.1.1 reads: &quot;A
translation unit that includes a header shall not contain any macros
that define names declared in that header.&quot; As I read this, it
would mean that the following program is legal:</p>
<pre>
#define npos 3.14
#include &lt;sstream&gt;
</pre>
<p>since npos is not defined in &lt;sstream&gt;. It is, however, defined
in &lt;string&gt;, and it is hard to imagine an implementation in
which &lt;sstream&gt; didn't include &lt;string&gt;.</p>
<p>I think that this phrase was probably formulated before it was
decided that a standard header may freely include other standard
headers. The phrase would be perfectly appropriate for C, for
example. In light of 17.4.4.1 paragraph 1, however,
it isn't stringent enough.</p>
<p><b>Proposed resolution:</b></p>
<p>In paragraph 2 of 17.4.3.1.1 , change &quot;A
translation unit that includes a header shall not contain any macros
that define names declared in that header.&quot; to &quot;A
translation unit that includes a header shall not contain any macros
that define names declared in any standard header.&quot;</p>
<p><i>[Copenhagen: the general idea is clearly correct, but there is
concern about making sure that the two paragraphs in 17.4.3.1.1 remain consistent. Nathan will provide new
wording.]</i></p>
<hr>
<a name="295"><h3>295.&nbsp;Is abs defined in &lt;cmath&gt;?</h3></a><p>
<b>Section:</b>&nbsp;26.5 <a href="lib-numerics.html#lib.c.math"> [lib.c.math]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Jens Maurer&nbsp; <b>Date:</b>&nbsp;12 Jan 2001</p>
<p>
Table 80 lists the contents of the &lt;cmath&gt; header. It does not
list <tt>abs()</tt>. However, 26.5, paragraph 6, which lists added
signatures present in &lt;cmath&gt;, does say that several overloads
of <tt>abs()</tt> should be defined in &lt;cmath&gt;.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Add <tt>abs</tt> to Table 80. Also, remove the parenthetical list
of functions &quot;(abs(), div(), rand(), srand())&quot; from 26.5 ,
paragraph 1.
</p>
<p><i>[Copenhagen: Modified proposed resolution so that it also gets
rid of that vestigial list of functions in paragraph 1.]</i></p>
<hr>
<a name="296"><h3>296.&nbsp;Missing descriptions and requirements of pair operators</h3></a><p>
<b>Section:</b>&nbsp;20.2.2 <a href="lib-utilities.html#lib.pairs"> [lib.pairs]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;14 Jan 2001</p>
<p>The synopsis of the header <tt>&lt;utility&gt;</tt> in 20.2
lists the complete set of equality and relational operators for <tt>pair</tt>
but the section describing the template and the operators only describes
<tt>operator==()</tt> and <tt>operator&lt;()</tt>, and it fails to mention
any requirements on the template arguments. The remaining operators are
not mentioned at all.
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following after 20.2.2 , paragraph 5:</p>
<blockquote>
<blockquote>
<tt>template &lt;class T1, class T2&gt;</tt>
<br><tt>bool operator!=(const pair&lt;T1, T2&gt;&amp; x, const pair&lt;T1,
T2&gt;&amp; y);</tt>
</blockquote>
<p>
<b>Requires: </b>Types <tt>T1</tt> and <tt>T2</tt> are
<tt>EqualityComparable</tt> (20.1.1 ).</p>
<p>
<b>Returns:</b> <tt>!(x == y)</tt>.</p>
</blockquote>
<p>Add the following after 20.2.2 , paragraph 6:</p>
<blockquote>
<blockquote>
<tt>template &lt;class T1, class T2&gt;</tt>
<br><tt>bool operator&gt;(const pair&lt;T1, T2&gt;&amp; x, const pair&lt;T1, T2&gt;&amp; y);</tt>
</blockquote>
<p>
<b>Requires: </b>Types <tt>T1</tt> and <tt>T2</tt> are
<tt>LessThanComparable</tt> (20.1.2 ).</p>
<p>
<b>Returns:</b> <tt>y &lt; x</tt>.</p>
<blockquote>
<tt>template &lt;class T1, class T2&gt;</tt>
<br><tt>bool operator&lt;=(const pair&lt;T1, T2&gt;&amp; x, const pair&lt;T1, T2&gt;&amp; y);</tt>
</blockquote>
<p>
<b>Requires: </b>Types <tt>T1</tt> and <tt>T2</tt> are
<tt>LessThanComparable</tt> (20.1.2 ).</p>
<p>
<b>Returns: </b><tt>!(y &lt; x)</tt>.</p>
<blockquote>
<tt>template &lt;class T1, class T2&gt;</tt>
<br><tt>bool operator&gt;=(const pair&lt;T1, T2&gt;&amp; x, const pair&lt;T1, T2&gt;&amp; y);</tt>
</blockquote>
<p>
<b>Requires: </b>Types <tt>T1</tt> and <tt>T2</tt> are
<tt>LessThanComparable</tt> (20.1.2 ).</p>
<p>
<b>Returns:</b> <tt>!(x &lt; y)</tt>.</p>
</blockquote>
<p><i>[post-Copenhagen: modified proposed resolution so that it does
not create a new section 20.2.2.1. That would violate ISO rules: we
cannot have 20.2.2.1 unless we also have 20.2.2.2.]</i></p>
<hr>
<a name="297"><h3>297.&nbsp;const_mem_fun_t&lt;&gt;::argument_type should be const T*</h3></a><p>
<b>Section:</b>&nbsp;20.3.8 <a href="lib-utilities.html#lib.member.pointer.adaptors"> [lib.member.pointer.adaptors]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;6 Jan 2001</p>
<p>The class templates <tt>const_mem_fun_t</tt> in 20.3.8, p8 and
<tt>const_mem_fun1_t</tt>
in 20.3.8, p9 derive from <tt>unary_function&lt;T*, S&gt;</tt>, and
<tt>binary_function&lt;T*,
A, S&gt;</tt>, respectively. Consequently, their <tt>argument_type</tt>, and
<tt>first_argument_type</tt>
members, respectively, are both defined to be <tt>T*</tt> (non-const).
However, their function call member operator takes a <tt>const T*</tt>
argument. It is my opinion that <tt>argument_type</tt> should be <tt>const
T*</tt> instead, so that one can easily refer to it in generic code. The
example below derived from existing code fails to compile due to the
discrepancy:
</p>
<p>
<tt>template &lt;class T&gt;</tt>
<br><tt>void foo (typename T::argument_type arg)&nbsp;&nbsp; // #1</tt>
<br><tt>{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; typename T::result_type (T::*pf) (typename
T::argument_type)
const =&nbsp;&nbsp; // #2</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;T::operator();</tt>
<br><tt>}</tt>
</p>
<p><tt>struct X { /* ... */ };</tt></p>
<p>
<tt>int main ()</tt>
<br><tt>{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; const X x;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; foo&lt;std::const_mem_fun_t&lt;void, X&gt;
&gt;(&amp;x);&nbsp;&nbsp;
// #3</tt>
<br><tt>}</tt>
</p>
<p>#1 <tt>foo()</tt> takes a plain unqualified <tt>X*</tt> as an argument
<br>#2 the type of the pointer is incompatible with the type of the member
function
<br>#3 the address of a constant being passed to a function taking a non-const
<tt>X*</tt>
</p>
<p><b>Proposed resolution:</b></p>
<p>Replace the top portion of the definition of the class template
const_mem_fun_t in 20.3.8, p8
</p>
<p>
<tt>template &lt;class S, class T&gt; class const_mem_fun_t</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : public
unary_function&lt;T*, S&gt; {</tt>
</p>
<p>with</p>
<p>
<tt>template &lt;class S, class T&gt; class const_mem_fun_t</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : public
unary_function&lt;<b>const</b> T*, S&gt; {</tt>
</p>
<p>Also replace the top portion of the definition of the class template
const_mem_fun1_t in 20.3.8, p9</p>
<p>
<tt>template &lt;class S, class T, class A&gt; class const_mem_fun1_t</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : public
binary_function&lt;T*, A, S&gt; {</tt>
</p>
<p>with</p>
<p>
<tt>template &lt;class S, class T, class A&gt; class const_mem_fun1_t</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : public
binary_function&lt;<b>const</b> T*, A, S&gt; {</tt>
</p>
<p><b>Rationale:</b></p>
<p>This is simply a contradiction: the <tt>argument_type</tt> typedef,
and the argument type itself, are not the same.</p>
<hr>
<a name="298"><h3>298.&nbsp;::operator delete[] requirement incorrect/insufficient</h3></a><p>
<b>Section:</b>&nbsp;18.4.1.2 <a href="lib-support.html#lib.new.delete.array"> [lib.new.delete.array]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;John A. Pedretti&nbsp; <b>Date:</b>&nbsp;10 Jan 2001</p>
<p>
The default behavior of <tt>operator delete[]</tt> described in 18.4.1.2, p12 -
namely that for non-null value of <i>ptr</i>, the operator reclaims storage
allocated by the earlier call to the default <tt>operator new[]</tt> - is not
correct in all cases. Since the specified <tt>operator new[]</tt> default
behavior is to call <tt>operator new</tt> (18.4.1.2, p4, p8), which can be
replaced, along with <tt>operator delete</tt>, by the user, to implement their
own memory management, the specified default behavior of<tt> operator
delete[]</tt> must be to call <tt>operator delete</tt>.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 18.4.1.2, p12 from</p>
<blockquote>
<b>-12-</b> <b>Default behavior:</b>
<ul>
<li>
For a null value of <i><tt>ptr</tt></i> , does nothing.
</li>
<li>
Any other value of <i><tt>ptr</tt></i> shall be a value returned
earlier by a call to the default <tt>operator new[](std::size_t)</tt>.
[Footnote: The value must not have been invalidated by an intervening
call to <tt>operator delete[](void*)</tt> (17.4.3.7 ).
--- end footnote]
For such a non-null value of <i><tt>ptr</tt></i> , reclaims storage
allocated by the earlier call to the default <tt>operator new[]</tt>.
</li>
</ul>
</blockquote>
<p>to</p>
<blockquote>
<b>-12-</b> <b>Default behavior: </b>Calls <tt>operator
delete(</tt><i>ptr</i>)
or <tt>operator delete(<i>ptr</i>, std::nothrow)</tt> respectively.
</blockquote>
<p>and expunge paragraph 13.</p>
<hr>
<a name="299"><h3>299.&nbsp;Incorrect return types for iterator dereference</h3></a><p>
<b>Section:</b>&nbsp;24.1.4 <a href="lib-iterators.html#lib.bidirectional.iterators"> [lib.bidirectional.iterators]</a>, 24.1.5 <a href="lib-iterators.html#lib.random.access.iterators"> [lib.random.access.iterators]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;John Potter&nbsp; <b>Date:</b>&nbsp;22 Jan 2001</p>
<p>
In section 24.1.4 ,
Table 75 gives the return type of *r-- as convertible to T. This is
not consistent with Table 74 which gives the return type of *r++ as
T&amp;. *r++ = t is valid while *r-- = t is invalid.
</p>
<p>
In section 24.1.5 ,
Table 76 gives the return type of a[n] as convertible to T. This is
not consistent with the semantics of *(a + n) which returns T&amp; by
Table 74. *(a + n) = t is valid while a[n] = t is invalid.
</p>
<p>
Discussion from the Copenhagen meeting: the first part is
uncontroversial. The second part, operator[] for Random Access
Iterators, requires more thought. There are reasonable arguments on
both sides. Return by value from operator[] enables some potentially
useful iterators, e.g. a random access &quot;iota iterator&quot; (a.k.a
&quot;counting iterator&quot; or &quot;int iterator&quot;). There isn't any obvious way
to do this with return-by-reference, since the reference would be to a
temporary. On the other hand, <tt>reverse_iterator</tt> takes an
arbitrary Random Access Iterator as template argument, and its
operator[] returns by reference. If we decided that the return type
in Table 76 was correct, we would have to change
<tt>reverse_iterator</tt>. This change would probably affect user
code.
</p>
<p>
History: the contradiction between <tt>reverse_iterator</tt> and the
Random Access Iterator requirements has been present from an early
stage. In both the STL proposal adopted by the committee
(N0527==94-0140) and the STL technical report (HPL-95-11 (R.1), by
Stepanov and Lee), the Random Access Iterator requirements say that
operator[]'s return value is &quot;convertible to T&quot;. In N0527
reverse_iterator's operator[] returns by value, but in HPL-95-11
(R.1), and in the STL implementation that HP released to the public,
reverse_iterator's operator[] returns by reference. In 1995, the
standard was amended to reflect the contents of HPL-95-11 (R.1). The
original intent for operator[] is unclear.
</p>
<p>
In the long term it may be desirable to add more fine-grained
iterator requirements, so that access method and traversal strategy
can be decoupled. (See &quot;Improved Iterator Categories and
Requirements&quot;, N1297 = 01-0011, by Jeremy Siek.) Any decisions
about issue 299 should keep this possibility in mind.
</p>
<p><b>Proposed resolution:</b></p>
<p>In section 24.1.4 , change the return type in table
75 from &quot;convertible to T&quot; to T&amp;.</p>
<p>In section 24.1.5 , change the return type in table
76 from &quot;convertible to T&quot; to T&amp;.</p>
<hr>
<a name="300"><h3>300.&nbsp;list::merge() specification incomplete</h3></a><p>
<b>Section:</b>&nbsp;23.2.2.4 <a href="lib-containers.html#lib.list.ops"> [lib.list.ops]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;John Pedretti&nbsp; <b>Date:</b>&nbsp;23 Jan 2001</p>
<p>
The &quot;Effects&quot; clause for list::merge() (23.2.2.4, p23)
appears to be incomplete: it doesn't cover the case where the argument
list is identical to *this (i.e., this == &amp;x). The requirement in the
note in p24 (below) is that x be empty after the merge which is surely
unintended in this case.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Change 23.2.2.4, p23 to:
</p>
<blockquote>
<b>Effects</b>: If &amp;x == this, does nothing; otherwise, merges the
argument list into the list.
</blockquote>
<p><i>[Copenhagen: The proposed resolution does not fix all of the
problems in 23.2.2.4 , p22-25. Three different
paragraphs (23, 24, 25) describe the effects of <tt>merge</tt>.
Changing p23, without changing the other two, appears to introduce
contradictions. Additionally, &quot;merges the argument list into the
list&quot; is excessively vague.]</i></p>
<hr>
<a name="301"><h3>301.&nbsp;basic_string template ctor effects clause omits allocator argument</h3></a><p>
<b>Section:</b>&nbsp;21.3.1 <a href="lib-strings.html#lib.string.cons"> [lib.string.cons]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;27 Jan 2001</p>
<p>
The effects clause for the basic_string template ctor in 21.3.1, p15
leaves out the third argument of type Allocator. I believe this to be
a mistake.
</p>
<p><b>Proposed resolution:</b></p>
<p>Replace</p>
<blockquote>
<p>
<b>-15- Effects:</b> If <i><tt>InputIterator</tt></i> is an integral
type, equivalent to</p>
<blockquote><tt>basic_string(static_cast&lt;size_type&gt;(begin),
static_cast&lt;value_type&gt;(end))</tt></blockquote>
</blockquote>
<p>with</p>
<blockquote>
<p>
<b>-15- Effects:</b> If <i><tt>InputIterator</tt></i> is an integral
type, equivalent to</p>
<blockquote><tt>basic_string(static_cast&lt;size_type&gt;(begin),
static_cast&lt;value_type&gt;(end), <b>a</b>)</tt></blockquote>
</blockquote>
<hr>
<a name="303"><h3>303.&nbsp;Bitset input operator underspecified</h3></a><p>
<b>Section:</b>&nbsp;23.3.5.3 <a href="lib-containers.html#lib.bitset.operators"> [lib.bitset.operators]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;5 Feb 2001</p>
<p>
In 23.3.5.3, we are told that <tt>bitset</tt>'s input operator
&quot;Extracts up to <i>N</i> (single-byte) characters from
<i>is</i>.&quot;, where <i>is</i> is a stream of type
<tt>basic_istream&lt;charT, traits&gt;</tt>.
</p>
<p>
The standard does not say what it means to extract single byte
characters from a stream whose character type, <tt>charT</tt>, is in
general not a single-byte character type. Existing implementations
differ.
</p>
<p>
A reasonable solution will probably involve <tt>widen()</tt> and/or
<tt>narrow()</tt>, since they are the supplied mechanism for a single
character between <tt>char</tt> and arbitrary <tt>charT</tt>.
</p>
<p>Narrowing the input characters is not the same as widening the
literals <tt>'0'</tt> and <tt>'1'</tt>, because there may be some
locales in which more than one wide character maps to the narrow
character <tt>'0'</tt>. Narrowing means that alternate
representations may be used for bitset input, widening means that
they may not be.</p>
<p>Note that for numeric input, <tt>num_get&lt;&gt;</tt>
(22.2.2.1.2/8) compares input characters to widened version of narrow
character literals.</p>
<p>From Pete Becker, in c++std-lib-8224:</p>
<blockquote>
<p>
Different writing systems can have different representations for the
digits that represent 0 and 1. For example, in the Unicode representation
of the Devanagari script (used in many of the Indic languages) the digit 0
is 0x0966, and the digit 1 is 0x0967. Calling narrow would translate those
into '0' and '1'. But Unicode also provides the ASCII values 0x0030 and
0x0031 for for the Latin representations of '0' and '1', as well as code
points for the same numeric values in several other scripts (Tamil has no
character for 0, but does have the digits 1-9), and any of these values
would also be narrowed to '0' and '1'.
</p>
<p>...</p>
<p>
It's fairly common to intermix both native and Latin
representations of numbers in a document. So I think the rule has to be
that if a wide character represents a digit whose value is 0 then the bit
should be cleared; if it represents a digit whose value is 1 then the bit
should be set; otherwise throw an exception. So in a Devanagari locale,
both 0x0966 and 0x0030 would clear the bit, and both 0x0967 and 0x0031
would set it. Widen can't do that. It would pick one of those two values,
and exclude the other one.
</p>
</blockquote>
<p>From Jens Maurer, in c++std-lib-8233:</p>
<blockquote>
<p>
Whatever we decide, I would find it most surprising if
bitset conversion worked differently from int conversion
with regard to alternate local representations of
numbers.
</p>
<p>Thus, I think the options are:</p>
<ul>
<li> Have a new defect issue for 22.2.2.1.2/8 so that it will
require the use of narrow().</li>
<li> Have a defect issue for bitset() which describes clearly
that widen() is to be used.</li>
</ul>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p>Replace the first two sentences of paragraph 5 with:</p>
<blockquote>
Extracts up to <i>N</i> characters from <i>is</i>. Stores these
characters in a temporary object <i>str</i> of type
<tt>basic_string&lt;charT, traits&gt;</tt>, then evaluates the
expression <tt><i>x</i> = bitset&lt;N&gt;(<i>str</i>)</tt>.
</blockquote>
<p>Replace the third bullet item in paragraph 5 with:</p>
<ul><li>
the next input character is neither <tt><i>is</i>.widen(0)</tt>
nor <tt><i>is</i>.widen(1)</tt> (in which case the input character
is not extracted).
</li></ul>
<p><b>Rationale:</b></p>
<p>Input for <tt>bitset</tt> should work the same way as numeric
input. Using <tt>widen</tt> does mean that alternative digit
representations will not be recognized, but this was a known
consequence of the design choice.</p>
<hr>
<a name="304"><h3>304.&nbsp;Must <tt>*a</tt> return an lvalue when <tt>a</tt> is an input iterator?</h3></a><p>
<b>Section:</b>&nbsp;24.1 <a href="lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Dave Abrahams&nbsp; <b>Date:</b>&nbsp;5 Feb 2001</p>
<p>
We all &quot;know&quot; that input iterators are allowed to produce
values when dereferenced of which there is no other in-memory copy.
</p>
<p>
But: Table 72, with a careful reading, seems to imply that this can only be
the case if the value_type has no members (e.g. is a built-in type).
</p>
<p>The problem occurs in the following entry:</p>
<pre>
a-&gt;m pre: (*a).m is well-defined
Equivalent to (*a).m
</pre>
<p>
<tt>*a.m</tt> can be well-defined if <tt>*a</tt> is not a reference
type, but since <tt>operator-&gt;()</tt> must return a pointer for
<tt>a-&gt;m</tt> to be well-formed, it needs something to return a
pointer <i>to</i>. This seems to indicate that <tt>*a</tt> must be
buffered somewhere to make a legal input iterator.
</p>
<p>I don't think this was intentional.</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Copenhagen: the two obvious possibilities are to keep the
<tt>operator-&gt;</tt> requirement for Input Iterators, and put
in a non-normative note describing how it can be implemented with
proxies, or else moving the <tt>operator-&gt;</tt> requirement
from Input Iterator to Forward Iterator. If we do the former
we'll also have to change <tt>istreambuf_iterator</tt>, because
it has no <tt>operator-&gt;</tt>. A straw poll showed roughly equal
support for the two options.]</i></p>
<hr>
<a name="305"><h3>305.&nbsp;Default behavior of codecvt&lt;wchar_t, char, mbstate_t&gt;::length()</h3></a><p>
<b>Section:</b>&nbsp;22.2.1.5.2 <a href="lib-locales.html#lib.locale.codecvt.virtuals"> [lib.locale.codecvt.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Howard Hinnant&nbsp; <b>Date:</b>&nbsp;24 Jan 2001</p>
<p>22.2.1.5/3 introduces codecvt in part with:</p>
<blockquote>
codecvt&lt;wchar_t,char,mbstate_t&gt; converts between the native
character sets for tiny and wide characters. Instantiations on
mbstate_t perform conversion between encodings known to the library
implementor.
</blockquote>
<p>But 22.2.1.5.2/10 describes do_length in part with:</p>
<blockquote>
... codecvt&lt;wchar_t, char, mbstate_t&gt; ... return(s) the lesser of max and
(from_end-from).
</blockquote>
<p>
The semantics of do_in and do_length are linked. What one does must
be consistent with what the other does. 22.2.1.5/3 leads me to
believe that the vendor is allowed to choose the algorithm that
codecvt&lt;wchar_t,char,mbstate_t&gt;::do_in performs so that it makes
his customers happy on a given platform. But 22.2.1.5.2/10 explicitly
says what codecvt&lt;wchar_t,char,mbstate_t&gt;::do_length must
return. And thus indirectly specifies the algorithm that
codecvt&lt;wchar_t,char,mbstate_t&gt;::do_in must perform. I believe
that this is not what was intended and is a defect.
</p>
<p>Discussion from the -lib reflector:
<br>This proposal would have the effect of making the semantics of
all of the virtual functions in <tt>codecvt&lt;wchar_t, char,
mbstate_t&gt;</tt> implementation specified. Is that what we want, or
do we want to mandate specific behavior for the base class virtuals
and leave the implementation specified behavior for the codecvt_byname
derived class? The tradeoff is that former allows implementors to
write a base class that actually does something useful, while the
latter gives users a way to get known and specified---albeit
useless---behavior, and is consistent with the way the standard
handles other facets. It is not clear what the original intention
was.</p>
<p>
Nathan has suggest a compromise: a character that is a widened version
of the characters in the basic execution character set must be
converted to a one-byte sequence, but there is no such requirement
for characters that are not part of the basic execution character set.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 22.2.1.5.2/10 from:</p>
<blockquote>
-10- Returns: (from_next-from) where from_next is the largest value in
the range [from,from_end] such that the sequence of values in the
range [from,from_next) represents max or fewer valid complete
characters of type internT. The instantiations required in Table 51
(21.1.1.1.1), namely codecvt&lt;wchar_t, char, mbstate_t&gt; and
codecvt&lt;char, char, mbstate_t&gt;, return the lesser of max and
(from_end-from).
</blockquote>
<p>to:</p>
<blockquote>
-10- Returns: (from_next-from) where from_next is the largest value in
the range [from,from_end] such that the sequence of values in the range
[from,from_next) represents max or fewer valid complete characters of
type internT. The instantiation codecvt&lt;char, char, mbstate_t&gt; returns
the lesser of max and (from_end-from).
</blockquote>
<p><i>[Copenhagen: straw poll was 3-1 in favor, with many abstentions.
Nathan would like to see more guarantees than are in the proposed
resolution. He will discuss this issue with the other people who
care about it.]</i></p>
<hr>
<a name="306"><h3>306.&nbsp;offsetof macro and non-POD types</h3></a><p>
<b>Section:</b>&nbsp;18.1 <a href="lib-support.html#lib.support.types"> [lib.support.types]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Steve Clamage&nbsp; <b>Date:</b>&nbsp;21 Feb 2001</p>
<p>Spliced together from reflector messages c++std-lib-8294 and -8295:</p>
<p>18.1, paragraph 5, reads: &quot;The macro <tt>offsetof</tt>
accepts a restricted set of <i>type</i> arguments in this
International Standard. <i>type</i> shall be a POD structure or a POD
union (clause 9). The result of applying the offsetof macro to a field
that is a static data member or a function member is
undefined.&quot;</p>
<p>For the POD requirement, it doesn't say &quot;no diagnostic
required&quot; or &quot;undefined behavior&quot;. I read 1.4 , paragraph 1, to mean that a diagnostic is required.
It's not clear whether this requirement was intended. While it's
possible to provide such a diagnostic, the extra complication doesn't
seem to add any value.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 18.1, paragraph 5, to &quot;If <i>type</i> is not a POD
structure or a POD union the results are undefined.&quot;</p>
<p><i>[Copenhagen: straw poll was 7-4 in favor. It was generally
agreed that requiring a diagnostic was inadvertent, but some LWG
members thought that diagnostics should be required whenever
possible.]</i></p>
<hr>
<a name="307"><h3>307.&nbsp;Lack of reference typedefs in container adaptors</h3></a><p>
<b>Section:</b>&nbsp;23.2.3 <a href="lib-containers.html#lib.container.adaptors"> [lib.container.adaptors]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Howard Hinnant&nbsp; <b>Date:</b>&nbsp;13 Mar 2001</p>
<p>From reflector message c++std-lib-8330. See also lib-8317.</p>
<p>
The standard is currently inconsistent in 23.2.3.2
paragraph 1 and 23.2.3.3 paragraph 1.
23.2.3.3/1, for example, says:
</p>
<blockquote>
-1- Any sequence supporting operations back(), push_back() and pop_back()
can be used to instantiate stack. In particular, vector (lib.vector), list
(lib.list) and deque (lib.deque) can be used.
</blockquote>
<p>But this is false: vector&lt;bool&gt; can not be used, because the
container adaptors return a T&amp; rather than using the underlying
container's reference type.</p>
<p>This is a contradiction that can be fixed by:</p>
<ol>
<li>Modifying these paragraphs to say that vector&lt;bool&gt;
is an exception.</li>
<li>Removing the vector&lt;bool&gt; specialization.</li>
<li>Changing the return types of stack and priority_queue to use
reference typedef's.</li>
</ol>
<p>
I propose 3. This does not preclude option 2 if we choose to do it
later (see issue <a href="lwg-active.html#96">96</a>); the issues are independent. Option
3 offers a small step towards support for proxied containers. This
small step fixes a current contradiction, is easy for vendors to
implement, is already implemented in at least one popular lib, and
does not break any code.
</p>
<p><b>Proposed resolution:</b></p>
<p>Summary: Add reference and const_reference typedefs to queue,
priority_queue and stack. Change return types of &quot;value_type&amp;&quot; to
&quot;reference&quot;. Change return types of &quot;const value_type&amp;&quot; to
&quot;const_reference&quot;. Details:</p>
<p>Change 23.2.3.1/1 from:</p>
<pre>
namespace std {
template &lt;class T, class Container = deque&lt;T&gt; &gt;
class queue {
public:
typedef typename Container::value_type value_type;
typedef typename Container::size_type size_type;
typedef Container container_type;
protected:
Container c;
public:
explicit queue(const Container&amp; = Container());
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
value_type&amp; front() { return c.front(); }
const value_type&amp; front() const { return c.front(); }
value_type&amp; back() { return c.back(); }
const value_type&amp; back() const { return c.back(); }
void push(const value_type&amp; x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
</pre>
<p>to:</p>
<pre>
namespace std {
template &lt;class T, class Container = deque&lt;T&gt; &gt;
class queue {
public:
typedef typename Container::value_type value_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::value_type value_type;
typedef typename Container::size_type size_type;
typedef Container container_type;
protected:
Container c;
public:
explicit queue(const Container&amp; = Container());
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference front() { return c.front(); }
const_reference front() const { return c.front(); }
reference back() { return c.back(); }
const_reference back() const { return c.back(); }
void push(const value_type&amp; x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
</pre>
<p>Change 23.2.3.2/1 from:</p>
<pre>
namespace std {
template &lt;class T, class Container = vector&lt;T&gt;,
class Compare = less&lt;typename Container::value_type&gt; &gt;
class priority_queue {
public:
typedef typename Container::value_type value_type;
typedef typename Container::size_type size_type;
typedef Container container_type;
protected:
Container c;
Compare comp;
public:
explicit priority_queue(const Compare&amp; x = Compare(),
const Container&amp; = Container());
template &lt;class InputIterator&gt;
priority_queue(InputIterator first, InputIterator last,
const Compare&amp; x = Compare(),
const Container&amp; = Container());
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
const value_type&amp; top() const { return c.front(); }
void push(const value_type&amp; x);
void pop();
};
// no equality is provided
}
</pre>
<p>to:</p>
<pre>
namespace std {
template &lt;class T, class Container = vector&lt;T&gt;,
class Compare = less&lt;typename Container::value_type&gt; &gt;
class priority_queue {
public:
typedef typename Container::value_type value_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::size_type size_type;
typedef Container container_type;
protected:
Container c;
Compare comp;
public:
explicit priority_queue(const Compare&amp; x = Compare(),
const Container&amp; = Container());
template &lt;class InputIterator&gt;
priority_queue(InputIterator first, InputIterator last,
const Compare&amp; x = Compare(),
const Container&amp; = Container());
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
const_reference top() const { return c.front(); }
void push(const value_type&amp; x);
void pop();
};
// no equality is provided
}
</pre>
<p>And change 23.2.3.3/1 from:</p>
<pre>
namespace std {
template &lt;class T, class Container = deque&lt;T&gt; &gt;
class stack {
public:
typedef typename Container::value_type value_type;
typedef typename Container::size_type size_type;
typedef Container container_type;
protected:
Container c;
public:
explicit stack(const Container&amp; = Container());
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
value_type&amp; top() { return c.back(); }
const value_type&amp; top() const { return c.back(); }
void push(const value_type&amp; x) { c.push_back(x); }
void pop() { c.pop_back(); }
};
template &lt;class T, class Container&gt;
bool operator==(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&lt; (const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator!=(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&gt; (const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&gt;=(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&lt;=(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
}
</pre>
<p>to:</p>
<pre>
namespace std {
template &lt;class T, class Container = deque&lt;T&gt; &gt;
class stack {
public:
typedef typename Container::value_type value_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::size_type size_type;
typedef Container container_type;
protected:
Container c;
public:
explicit stack(const Container&amp; = Container());
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference top() { return c.back(); }
const_reference top() const { return c.back(); }
void push(const value_type&amp; x) { c.push_back(x); }
void pop() { c.pop_back(); }
};
template &lt;class T, class Container&gt;
bool operator==(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&lt; (const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator!=(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&gt; (const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&gt;=(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
template &lt;class T, class Container&gt;
bool operator&lt;=(const stack&lt;T, Container&gt;&amp; x,
const stack&lt;T, Container&gt;&amp; y);
}
</pre>
<p><i>[Copenhagen: This change was discussed before the IS was released
and it was deliberately not adopted. Nevertheless, the LWG believes
(straw poll: 10-2) that it is a genuine defect.]</i></p>
<hr>
<a name="308"><h3>308.&nbsp;Table 82 mentions unrelated headers</h3></a><p>
<b>Section:</b>&nbsp;27 <a href="lib-iostreams.html#lib.input.output"> [lib.input.output]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;15 Mar 2001</p>
<p>
Table 82 in section 27 mentions the header &lt;cstdlib&gt; for String
streams (27.7 ) and the headers &lt;cstdio&gt; and
&lt;cwchar&gt; for File streams (27.8 ). It's not clear
why these headers are mentioned in this context since they do not
define any of the library entities described by the
subclauses. According to 17.4.1.1 , only such headers
are to be listed in the summary.
</p>
<p><b>Proposed resolution:</b></p>
<p>Remove &lt;cstdlib&gt; and &lt;cwchar&gt; from
Table 82.</p>
<p><i>[Copenhagen: changed the proposed resolution slightly. The
original proposed resolution also said to remove &lt;cstdio&gt; from
Table 82. However, &lt;cstdio&gt; is mentioned several times within
section 27.8 , including 27.8.2 .]</i></p>
<hr>
<a name="309"><h3>309.&nbsp;Does sentry catch exceptions?</h3></a><p>
<b>Section:</b>&nbsp;27.6 <a href="lib-iostreams.html#lib.iostream.format"> [lib.iostream.format]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Open">Open</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;19 Mar 2001</p>
<p>
The descriptions of the constructors of basic_istream&lt;&gt;::sentry
(27.6.1.1.2 ) and basic_ostream&lt;&gt;::sentry
(27.6.2.3 ) do not explain what the functions do in
case an exception is thrown while they execute. Some current
implementations allow all exceptions to propagate, others catch them
and set ios_base::badbit instead, still others catch some but let
others propagate.
</p>
<p>
The text also mentions that the functions may call setstate(failbit)
(without actually saying on what object, but presumably the stream
argument is meant). That may have been fine for
basic_istream&lt;&gt;::sentry prior to issue <a href="lwg-defects.html#195">195</a>, since
the function performs an input operation which may fail. However,
issue <a href="lwg-defects.html#195">195</a> amends 27.6.1.1.2 , p2 to
clarify that the function should actually call setstate(failbit |
eofbit), so the sentence in p3 is redundant or even somewhat
contradictory.
</p>
<p>
The same sentence that appears in 27.6.2.3 , p3
doesn't seem to be very meaningful for basic_istream&lt;&gt;::sentry
which performs no input. It is actually rather misleading since it
would appear to guide library implementers to calling
setstate(failbit) when os.tie()-&gt;flush(), the only called function,
throws an exception (typically, it's badbit that's set in response to
such an event).
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following paragraph immediately after
27.6.1.1.2 , p5</p>
<blockquote>
<p>
If an exception is thrown during the preparation then ios::badbit
is turned on* in is's error state.
</p>
<p>
[Footnote: This is done without causing an ios::failure to be thrown.
--- end footnote]
</p>
<p>
If (is.exceptions() &amp; ios_base::badbit)!= 0 then the exception is
rethrown.
</p>
</blockquote>
<p>And strike the following sentence from 27.6.1.1.2 , p5</p>
<blockquote>
During preparation, the constructor may call setstate(failbit)
(which may throw ios_base::failure (lib.iostate.flags))
</blockquote>
<p>Add the following paragraph immediately after
27.6.2.3 , p3</p>
<blockquote>
<p>
If an exception is thrown during the preparation then ios::badbit
is turned on* in os's error state.
</p>
<p>
[Footnote: This is done without causing an ios::failure to be
thrown. --- end footnote]
</p>
<p>
If (os.exceptions() &amp; ios_base::badbit)!= 0 then the exception
is rethrown.
</p>
</blockquote>
<p>And strike the following sentence from 27.6.2.3 , p3</p>
<blockquote>
During preparation, the constructor may call setstate(failbit)
(which may throw ios_base::failure (lib.iostate.flags))
</blockquote>
<p>(Note that the removal of the two sentences means that the ctors
will not be able to report the failure of any implementation-dependent
operations referred to in footnotes 280 and 293, unless such
operations throw an exception.)</p>
<p><i>[
Copenhagen: It was agreed that there was an issue here, but there was
disagreement about the resolution. Some LWG members argued that a
sentry's constructor should not catch exceptions, because sentries
should only be used within (un)formatted input functions and that
exception handling is the responsibility of those functions, not of
the sentries.
]</i></p>
<hr>
<a name="310"><h3>310.&nbsp;Is errno a macro?</h3></a><p>
<b>Section:</b>&nbsp;17.4.1.2 <a href="lib-intro.html#lib.headers"> [lib.headers]</a>, 19.3 <a href="lib-diagnostics.html#lib.errno"> [lib.errno]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Steve Clamage&nbsp; <b>Date:</b>&nbsp;21 Mar 2001</p>
<p>
Exactly how should errno be declared in a conforming C++ header?
</p>
<p>
The C standard says in 7.1.4 that it is unspecified whether errno is a
macro or an identifier with external linkage. In some implementations
it can be either, depending on compile-time options. (E.g., on
Solaris in multi-threading mode, errno is a macro that expands to a
function call, but is an extern int otherwise. &quot;Unspecified&quot; allows
such variability.)
</p>
<p>The C++ standard:</p>
<ul>
<li>17.4.1.2 says in a note that errno must be macro in C. (false)</li>
<li>17.4.3.1.3 footnote 166 says errno is reserved as an external
name (true), and implies that it is an identifier.</li>
<li>19.3 simply lists errno as a macro (by what reasoning?) and goes
on to say that the contents of of C++ &lt;errno.h&gt; are the
same as in C, begging the question.</li>
<li>C.2, table 95 lists errno as a macro, without comment.</li>
</ul>
<p>I find no other references to errno.</p>
<p>We should either explicitly say that errno must be a macro, even
though it need not be a macro in C, or else explicitly leave it
unspecified. We also need to say something about namespace std.
A user who includes &lt;cerrno&gt; needs to know whether to write
<tt>errno</tt>, or <tt>::errno</tt>, or <tt>std::errno</tt>, or
else &lt;cerrno&gt; is useless.</p>
<p>Two acceptable fixes:</p>
<ul>
<li><p>errno must be a macro. This is trivially satisfied by adding<br>
&nbsp;&nbsp;#define errno (::std::errno)<br>
to the headers if errno is not already a macro. You then always
write errno without any scope qualification, and it always expands
to a correct reference. Since it is always a macro, you know to
avoid using errno as a local identifer.</p></li>
<li><p>errno is in the global namespace. This fix is inferior, because
::errno is not guaranteed to be well-formed.</p></li>
</ul>
<p><i>[
This issue was first raised in 1999, but it slipped through
the cracks.
]</i></p>
<p><b>Proposed resolution:</b></p>
<p>Change the Note in section 17.4.1.2p5 from</p>
<blockquote>
Note: the names defined as macros in C include the following:
assert, errno, offsetof, setjmp, va_arg, va_end, and va_start.
</blockquote>
<p>to</p>
<blockquote>
Note: the names defined as macros in C include the following:
assert, offsetof, setjmp, va_arg, va_end, and va_start.
</blockquote>
<p>In section 19.3, change paragraph 2 from</p>
<blockquote>
The contents are the same as the Standard C library header
&lt;errno.h&gt;.
</blockquote>
<p>to</p>
<blockquote>
The contents are the same as the Standard C library header
&lt;errno.h&gt;, except that errno shall be defined as a macro.
</blockquote>
<hr>
<a name="311"><h3>311.&nbsp;Incorrect wording in basic_ostream class synopsis</h3></a><p>
<b>Section:</b>&nbsp;27.6.2.1 <a href="lib-iostreams.html#lib.ostream"> [lib.ostream]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Review">Review</a>&nbsp; <b>Submitter:</b>&nbsp;Andy Sawyer&nbsp; <b>Date:</b>&nbsp;21 Mar 2001</p>
<p>In 27.6.2.1 , the synopsis of class basic_ostream says:</p>
<pre>
// partial specializationss
template&lt;class traits&gt;
basic_ostream&lt;char,traits&gt;&amp; operator&lt;&lt;( basic_ostream&lt;char,traits&gt;&amp;,
const char * );
</pre>
<p>Problems:</p>
<ul>
<li>Too many 's's at the end of &quot;specializationss&quot; </li>
<li>This is an overload, not a partial specialization</li>
</ul>
<p><b>Proposed resolution:</b></p>
<p>In the synopsis in 27.6.2.1 , remove the
<i>// partial specializationss</i> comment.</p>
<hr>
<a name="312"><h3>312.&nbsp;Table 27 is missing headers</h3></a><p>
<b>Section:</b>&nbsp;20 <a href="lib-utilities.html#lib.utilities"> [lib.utilities]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#Ready">Ready</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;29 Mar 2001</p>
<p>Table 27 in section 20 lists the header &lt;memory&gt; (only) for
Memory (lib.memory) but neglects to mention the headers
&lt;cstdlib&gt; and &lt;cstring&gt; that are discussed in 20.4.6 .</p>
<p><b>Proposed resolution:</b></p>
<p>Add &lt;cstdlib&gt; and &lt;cstring&gt; to Table 27, in the same row
as &lt;memory&gt;.</p>
<hr>
<a name="315"><h3>315.&nbsp;Bad &quot;range&quot; in list::unique complexity</h3></a><p>
<b>Section:</b>&nbsp;23.2.2.4 <a href="lib-containers.html#lib.list.ops"> [lib.list.ops]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Andy Sawyer&nbsp; <b>Date:</b>&nbsp;1 May 2001</p>
<p>
23.2.2.4 , Para 21 describes the complexity of
list::unique as: &quot;If the range (last - first) is not empty, exactly
(last - first) -1 applications of the corresponding predicate,
otherwise no applications of the predicate)&quot;.
</p>
<p>
&quot;(last - first)&quot; is not a range.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Change the &quot;range&quot; from (last - first) to [first, last). Change the
complexity from &quot;(last - first) -1 applications of the corresponding
predicate&quot; to &quot;distance(first,last)-1 applications of the corresponding
predicate.
</p>
<hr>
<a name="316"><h3>316.&nbsp;Vague text in Table 69</h3></a><p>
<b>Section:</b>&nbsp;23.1.2 <a href="lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;4 May 2001</p>
<p>Table 69 says this about a_uniq.insert(t):</p>
<blockquote>
inserts t if and only if there is no element in the container with key
equivalent to the key of t. The bool component of the returned pair
indicates whether the insertion takes place and the iterator component of the
pair points to the element with key equivalent to the key of t.
</blockquote>
<p>The description should be more specific about exactly how the bool component
indicates whether the insertion takes place.</p>
<p><b>Proposed resolution:</b></p>
<p>Change the text in question to</p>
<blockquote>
...The bool component of the returned pair is true if and only if the insertion
takes place...
</blockquote>
<hr>
<a name="317"><h3>317.&nbsp;Instantiation vs. specialization of facets</h3></a><p>
<b>Section:</b>&nbsp;22 <a href="lib-locales.html#lib.localization"> [lib.localization]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;4 May 2001</p>
<p>
The localization section of the standard refers to specializations of
the facet templates as instantiations even though the required facets
are typically specialized rather than explicitly (or implicitly)
instantiated. In the case of ctype&lt;char&gt; and
ctype_byname&lt;char&gt; (and the wchar_t versions), these facets are
actually required to be specialized. The terminology should be
corrected to make it clear that the standard doesn't mandate explicit
instantiation (the term specialization encompasses both explicit
instantiations and specializations).
</p>
<p><b>Proposed resolution:</b></p>
<p>
In the following paragraphs, replace all occurrences of the word
instantiation or instantiations with specialization or specializations,
respectively:
</p>
<blockquote>
22.1.1.1.1, p4, Table 52, 22.2.1.1, p2, 22.2.1.5, p3, 22.2.1.5.1, p5,
22.2.1.5.2, p10, 22.2.2, p2, 22.2.3.1, p1, 22.2.3.1.2, p1, p2 and p3,
22.2.4.1, p1, 22.2.4.1.2, p1, 22,2,5, p1, 22,2,6, p2, 22.2.6.3.2, p7, and
Footnote 242.
</blockquote>
<p>And change the text in 22.1.1.1.1, p4 from</p>
<blockquote>
An implementation is required to provide those instantiations
for facet templates identified as members of a category, and
for those shown in Table 52:
</blockquote>
<p>to</p>
<blockquote>
An implementation is required to support those specializations...
</blockquote>
<hr>
<a name="318"><h3>318.&nbsp;Misleading comment in definition of numpunct_byname</h3></a><p>
<b>Section:</b>&nbsp;22.2.3.2 <a href="lib-locales.html#lib.locale.numpunct.byname"> [lib.locale.numpunct.byname]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;12 May 2001</p>
<p>The definition of the numpunct_byname template contains the following
comment:</p>
<pre>
namespace std {
template &lt;class charT&gt;
class numpunct_byname : public numpunct&lt;charT&gt; {
// this class is specialized for char and wchar_t.
...
</pre>
<p>There is no documentation of the specializations and it seems
conceivable that an implementation will not explicitly specialize the
template at all, but simply provide the primary template.</p>
<p><b>Proposed resolution:</b></p>
<p>Remove the comment from the text in 22.2.3.2 and from the proposed
resolution of library issue <a href="lwg-active.html#228">228</a>.</p>
<hr>
<a name="319"><h3>319.&nbsp;Storage allocation wording confuses &quot;Required behavior&quot;, &quot;Requires&quot;</h3></a><p>
<b>Section:</b>&nbsp;18.4.1.1 <a href="lib-support.html#lib.new.delete.single"> [lib.new.delete.single]</a>, 18.4.1.2 <a href="lib-support.html#lib.new.delete.array"> [lib.new.delete.array]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Beman Dawes&nbsp; <b>Date:</b>&nbsp;15 May 2001</p>
<p>The standard specifies 17.3.1.3 that &quot;Required
behavior&quot; elements describe &quot;the semantics of a function definition
provided by either the implementation or a C++ program.&quot;</p>
<p>The standard specifies 17.3.1.3 that &quot;Requires&quot;
elements describe &quot;the preconditions for calling the function.&quot;</p>
<p>In the sections noted below, the current wording specifies
&quot;Required Behavior&quot; for what are actually preconditions, and thus
should be specified as &quot;Requires&quot;.</p>
<p><b>Proposed resolution:</b></p>
<p>In 18.4.1.1 Para 12 Change:</p>
<blockquote>
<p>Required behavior: accept a value of ptr that is null or that was
returned by an earlier call ...</p>
</blockquote>
<p>to:</p>
<blockquote>
<p>Requires: the value of ptr be null or the value returned by an
earlier call ...</p>
</blockquote>
<p>In 18.4.1.2 Para 11 Change:</p>
<blockquote>
<p>Required behavior: accept a value of ptr that is null or that was
returned by an earlier call ...</p>
</blockquote>
<p>to:</p>
<blockquote>
<p>Requires: the value of ptr be null or the value returned by an
earlier call ...</p>
</blockquote>
<hr>
<a name="320"><h3>320.&nbsp;list::assign overspecified</h3></a><p>
<b>Section:</b>&nbsp;23.2.2.1 <a href="lib-containers.html#lib.list.cons"> [lib.list.cons]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Howard Hinnant&nbsp; <b>Date:</b>&nbsp;17 May 2001</p>
<p>
Section 23.2.2.1, paragraphs 6-8 specify that list assign (both forms) have
the &quot;effects&quot; of a call to erase followed by a call to insert.
</p>
<p>
I would like to document that implementers have the freedom to implement
assign by other methods, as long as the end result is the same and the
exception guarantee is as good or better than the basic guarantee.
</p>
<p>
The motivation for this is to use T's assignment operator to recycle
existing nodes in the list instead of erasing them and reallocating
them with new values. It is also worth noting that, with careful
coding, most common cases of assign (everything but assignment with
true input iterators) can elevate the exception safety to strong if
T's assignment has a nothrow guarantee (with no extra memory cost).
Metrowerks does this. However I do not propose that this subtlety be
standardized. It is a QoI issue. </p>
<p>Existing practise:
Metrowerks and SGI recycle nodes, Dinkumware and Rogue Wave don't.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 23.2.2.1/7 from:</p>
<blockquote>
<p>Effects:</p>
<pre>
erase(begin(), end());
insert(begin(), first, last);
</pre>
</blockquote>
<p>to:</p>
<blockquote>
<p>Effects: Replaces the contents of the list with the range [first, last).</p>
<p>PostCondition: *this == list&lt;T, Allocator&gt;(first, last)</p>
<p>Notes: If an exception is thrown, the contents of the list are
indeterminate.</p>
</blockquote>
<p>Change 23.2.2.1/8 from:</p>
<blockquote>
<p>Effects:</p>
<pre>
erase(begin(), end());
insert(begin(), n, t);
</pre>
</blockquote>
<p>to:</p>
<blockquote>
<p>Effects: Replaces the contents of the list with n copies of t.</p>
<p>PostCondition: *this == list&lt;T, Allocator&gt;(n, t)</p>
<p>Notes: If an exception is thrown, the contents of the list are self
consistent but indeterminate.</p>
</blockquote>
<hr>
<a name="321"><h3>321.&nbsp;Typo in num_get</h3></a><p>
<b>Section:</b>&nbsp;22.2.2.1.2 <a href="lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Kevin Djang&nbsp; <b>Date:</b>&nbsp;17 May 2001</p>
<p>
Section 22.2.2.1.2 at p7 states that &quot;A length specifier is added to
the conversion function, if needed, as indicated in Table 56.&quot;
However, Table 56 uses the term &quot;length modifier&quot;, not &quot;length
specifier&quot;.
</p>
<p><b>Proposed resolution:</b></p>
<p>
In 22.2.2.1.2 at p7, change the text &quot;A length specifier is added ...&quot;
to be &quot;A length modifier is added ...&quot;
</p>
<hr>
<a name="322"><h3>322.&nbsp;iterator and const_iterator should have the same value type</h3></a><p>
<b>Section:</b>&nbsp;23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Matt Austern&nbsp; <b>Date:</b>&nbsp;17 May 2001</p>
<p>
It's widely assumed that, if X is a container,
iterator_traits&lt;X::iterator&gt;::value_type and
iterator_traits&lt;X::const_iterator&gt;::value_type should both be
X::value_type. However, this is nowhere stated. The language in
Table 65 is not precise about the iterators' value types (it predates
iterator_traits), and could even be interpreted as saying that
iterator_traits&lt;X::const_iterator&gt;::value_type should be &quot;const
X::value_type&quot;.
</p>
<p>Related issue: <a href="lwg-closed.html#279">279</a>.</p>
<p><b>Proposed resolution:</b></p>
<p>In Table 65 (&quot;Container Requirements&quot;), change the return type for
X::iterator to &quot;iterator type whose value type is T&quot;. Change the
return type for X::const_iterator to &quot;constant iterator type whose
value type is T&quot;.</p>
<p><b>Rationale:</b></p>
<p>
This belongs as a container requirement, rather than an iterator
requirement, because the whole notion of iterator/const_iterator
pairs is specific to containers' iterator.
</p>
<p>
It is existing practice that (for example)
iterator_traits&lt;list&lt;int&gt;::const_iterator&gt;::value_type
is &quot;int&quot;, rather than &quot;const int&quot;. This is consistent with
the way that const pointers are handled: the standard already
requires that iterator_traits&lt;const int*&gt;::value_type is int.
</p>
<hr>
<a name="323"><h3>323.&nbsp;abs() overloads in different headers</h3></a><p>
<b>Section:</b>&nbsp;26.5 <a href="lib-numerics.html#lib.c.math"> [lib.c.math]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Dave Abrahams&nbsp; <b>Date:</b>&nbsp;4 June 2001</p>
<p>Currently the standard mandates the following overloads of
abs():</p>
<pre>
abs(long), abs(int) in &lt;cstdlib&gt;
abs(float), abs(double), abs(long double) in &lt;cmath&gt;
template&lt;class T&gt; T abs(const complex&lt;T&gt;&amp;) in &lt;complex&gt;
template&lt;class T&gt; valarray&lt;T&gt; abs(const valarray&lt;T&gt;&amp;); in &lt;valarray&gt;
</pre>
<p>
The problem is that having only some overloads visible of a function
that works on &quot;implicitly inter-convertible&quot; types is dangerous in
practice. The headers that get included at any point in a translation
unit can change unpredictably during program
development/maintenance. The wrong overload might be unintentionally
selected.
</p>
<p>
Currently, there is nothing that mandates the simultaneous visibility
of these overloads. Indeed, some vendors have begun fastidiously
reducing dependencies among their (public) headers as a QOI issue: it
helps people to write portable code by refusing to compile unless all
the correct headers are #included.
</p>
<p>The same issue may exist for other functions in the library.</p>
<p><b>Proposed resolution:</b></p>
<hr>
<a name="324"><h3>324.&nbsp;Do output iterators have value types?</h3></a><p>
<b>Section:</b>&nbsp;24.1.2 <a href="lib-iterators.html#lib.output.iterators"> [lib.output.iterators]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Dave Abrahams&nbsp; <b>Date:</b>&nbsp;7 June 2001</p>
<p>Table 73 suggests that output iterators have value types. It says
defines the expression &quot;*a = t&quot;. Additionally, although Table 73
never lists &quot;a = t&quot; or &quot;X(a) = t&quot; in the &quot;expressions&quot; column, it
contains a note saying that &quot;a = t&quot; and &quot;X(a) = t&quot; have equivalent
(but nowhere specified!) semantics.</p>
<p>According to 24.1/9, t is supposed to be &quot;a value of value type
T&quot;:</p>
<blockquote>
In the following sections, a and b denote values of X, n denotes a
value of the difference type Distance, u, tmp, and m denote
identifiers, r denotes a value of X&amp;, t denotes a value of
value type T.
</blockquote>
<p>Two other parts of the standard that are relevant to whether
output iterators have value types:</p>
<ul>
<li>24.1/1 says &quot;All iterators i support the expression *i,
resulting in a value of some class, enumeration, or built-in type
T, called the value type of the iterator&quot;.</li>
<li>
24.3.1/1, which says &quot;In the case of an output iterator, the types
iterator_traits&lt;Iterator&gt;::difference_type
iterator_traits&lt;Iterator&gt;::value_type are both defined as void.&quot;
</li>
</ul>
<p>The first of these passages suggests that &quot;*i&quot; is supposed to
return a useful value, which contradicts the note in 24.1.2/2 saying
that the only valid use of &quot;*i&quot; for output iterators is in an
expression of the form &quot;*i = t&quot;. The second of these passages appears
to contradict Table 73, because it suggests that &quot;*i&quot;'s return value
should be void. The second passage is also broken in the case of a an
iterator type, like non-const pointers, that satisfies both the output
iterator requirements and the forward iterator requirements.</p>
<p>What should the standard say about &quot;*i's&quot; return value when i is an
output iterator, and what should it say about that t is in the
expression &quot;*i = t&quot;? Finally, should the standard say anything about
output iterators' pointer and reference types?</p>
<p><b>Proposed resolution:</b></p>
<p>A sketch of one proposed resolution, without language: Make it
clear that the notion of &quot;value type&quot; does not apply to output
iterators.</p>
<blockquote>
Put an &quot;except for output iterators&quot; qualification in 24.1/1; remove
the note in table 73 about &quot;a = t&quot; and &quot;X(a) = t&quot;; put language in
24.1.2 paragraph 1 saying that &quot;t&quot; is a value of whatever type or
types for which &quot;*i = t&quot; is defined and that an output iterator need
not have a unique value type; change 24.3.1/1 to say that an output
iterator may, but need not, define
iterator_traits&lt;Iterator&gt;::difference_type
iterator_traits&lt;Iterator&gt;::value_type as void.
</blockquote>
<p>A sketch of an alternate proposed resolution, also without
language: Require every output iterator to have a value type, just
like other kinds of iterators.</p>
<blockquote>
Put an &quot;except for output iterators&quot; qualification in 24.1/1; remove
the note in table 73 about &quot;a = t&quot; and &quot;X(a) = t&quot;; put language in
24.1.2 paragraph 1 saying that an output iterator's value type is the
type for which &quot;*i = t&quot; is defined; remove the note in 24.3.1/1 saying
that iterator_traits&lt;&gt;::value_type is void for an output
iterator; change all of the predefined output iterators
(ostream_iterator, ostreambuf_iterator, back_insert_iterator,
front_insert_iterator, insert_iterator) so that they have non-void
value types.
</blockquote>
<hr>
<a name="325"><h3>325.&nbsp;Misleading text in moneypunct&lt;&gt;::do_grouping</h3></a><p>
<b>Section:</b>&nbsp;22.2.6.3.2 <a href="lib-locales.html#lib.locale.moneypunct.virtuals"> [lib.locale.moneypunct.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;02 Jul 2001</p>
<p>The Returns clause in 22.2.6.3.2, p3 says about
moneypunct&lt;charT&gt;::do_grouping()
</p>
<blockquote>
Returns: A pattern defined identically as the result of
numpunct&lt;charT&gt;::do_grouping().241)
</blockquote>
<p>Footnote 241 then reads</p>
<blockquote>
This is most commonly the value &quot;\003&quot; (not &quot;3&quot;).
</blockquote>
<p>
The returns clause seems to imply that the two member functions must
return an identical value which in reality may or may not be true,
since the facets are usually implemented in terms of struct std::lconv
and return the value of the grouping and mon_grouping, respectively.
The footnote also implies that the member function of the moneypunct
facet (rather than the overridden virtual functions in moneypunct_byname)
most commonly return &quot;\003&quot;, which contradicts the C standard which
specifies the value of &quot;&quot; for the (most common) C locale.
</p>
<p><b>Proposed resolution:</b></p>
<p>Replace the text in Returns clause in 22.2.6.3.2, p3 with the following:</p>
<blockquote>
Returns: A pattern defined identically as, but not necessarily
equal to, the result of numpunct&lt;charT&gt;::do_grouping().241)
</blockquote>
<p>and replace the text in Footnote 241 with the following:</p>
<blockquote>
The moneypunct facet (or its derivative) installed in named locales
other than &quot;C&quot; will most commonly return the value &quot;\003&quot; (not &quot;3&quot;).
</blockquote>
<p><b>Rationale:</b></p>
<p>
Note that the proposed resolution is sufficiently vague to allow
implementations to implement the behavior of both moneypunct and
moneypunct_byname to be implemented by the base. This may or may
not be desirable depending on whether we want the base behavior
to strictly reflect the &quot;C&quot; locale (only) and the derived behavior
to implement the behavior specific to the named locales. This
distinction would be detectable by obtaining a reference to
moneypunct_byname, say mp, and calling mp.do_grouping() or
mp.moneypunct&lt;charT&gt;::do_grouping() to get one or the other.
</p>
<hr>
<a name="326"><h3>326.&nbsp;Missing typedef in moneypunct_byname</h3></a><p>
<b>Section:</b>&nbsp;22.2.6.4 <a href="lib-locales.html#lib.locale.moneypunct.byname"> [lib.locale.moneypunct.byname]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;05 Jul 2001</p>
<p>The definition of the moneypunct facet contains the typedefs char_type
and string_type. Only one of these names, string_type, is defined in
the derived facet, moneypunct_byname.</p>
<p><b>Proposed resolution:</b></p>
<p>For consistency with the numpunct facet, add a typedef for
char_type to the definition of the moneypunct_byname facet in
22.2.6.4 .</p>
<hr>
<a name="327"><h3>327.&nbsp;Typo in time_get facet in table 52</h3></a><p>
<b>Section:</b>&nbsp;22.1.1.1.1 <a href="lib-locales.html#lib.locale.category"> [lib.locale.category]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Tiki Wan&nbsp; <b>Date:</b>&nbsp;06 Jul 2001</p>
<p>The <tt>wchar_t</tt> versions of <tt>time_get</tt> and
<tt>time_get_byname</tt> are listed incorrectly in table 52,
required instantiations. In both cases the second template
parameter is given as OutputIterator. It should instead be
InputIterator, since these are input facets.</p>
<p><b>Proposed resolution:</b></p>
<p>
In table 52, required instantiations, in
22.1.1.1.1 , change</p>
<pre>
time_get&lt;wchar_t, OutputIterator&gt;
time_get_byname&lt;wchart, OutputIterator&gt;
</pre>
<p>to</p>
<pre>
time_get&lt;wchar_t, InputIterator&gt;
time_get_byname&lt;wchart, InputIterator&gt;
</pre>
<hr>
<a name="328"><h3>328.&nbsp;Bad sprintf format modifier in money_put&lt;&gt;::do_put()</h3></a><p>
<b>Section:</b>&nbsp;22.2.6.2.2 <a href="lib-locales.html#lib.locale.money.put.virtuals"> [lib.locale.money.put.virtuals]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;07 Jul 2001</p>
<p>The sprintf format string , &quot;%.01f&quot; (that's the digit one), in the
description of the do_put() member functions of the money_put facet in
22.2.6.2.2, p1 is incorrect. First, the f format specifier is wrong
for values of type long double, and second, the precision of 01
doesn't seem to make sense. What was most likely intended was
&quot;%.0Lf&quot;., that is a precision of zero followed by the L length
modifier.</p>
<p><b>Proposed resolution:</b></p>
<p>Change the format string to &quot;%.0Lf&quot;.</p>
<hr>
<a name="329"><h3>329.&nbsp;vector capacity, reserve and reallocation</h3></a><p>
<b>Section:</b>&nbsp;23.2.4.2 <a href="lib-containers.html#lib.vector.capacity"> [lib.vector.capacity]</a>, 23.2.4.3 <a href="lib-containers.html#lib.vector.modifiers"> [lib.vector.modifiers]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Anthony Williams&nbsp; <b>Date:</b>&nbsp;13 Jul 2001</p>
<p>
There is an apparent contradiction about which circumstances can cause
a reallocation of a vector in Section 23.2.4.2 and
section 23.2.4.3 .
</p>
<p>23.2.4.2p5 says:</p>
<blockquote>
Notes: Reallocation invalidates all the references, pointers, and iterators
referring to the elements in the sequence. It is guaranteed that no
reallocation takes place during insertions that happen after a call to
reserve() until the time when an insertion would make the size of the vector
greater than the size specified in the most recent call to reserve().
</blockquote>
<p>Which implies if I do</p>
<pre>
std::vector&lt;int&gt; vec;
vec.reserve(23);
vec.reserve(0);
vec.insert(vec.end(),1);
</pre>
<p>then the implementation may reallocate the vector for the insert,
as the size specified in the previous call to reserve was zero.</p>
<p>However, the previous paragraphs (23.2.4.2, p1-2) state:</p>
<blockquote>
<p>
(capacity) Returns: The total number of elements the vector
can hold without requiring reallocation
</p>
<p>
...After reserve(), capacity() is greater or equal to the
argument of reserve if reallocation happens; and equal to the previous value
of capacity() otherwise...
</p>
</blockquote>
<p>
This implies that vec.capacity() is still 23, and so the insert()
should not require a reallocation, as vec.size() is 0. This is backed
up by 23.2.4.3p1:
</p>
<blockquote>
(insert) Notes: Causes reallocation if the new size is greater than the old
capacity.
</blockquote>
<p>
Though this doesn't rule out reallocation if the new size is less
than the old capacity, I think the intent is clear.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the wording of 23.2.4.5p5 to:</p>
<blockquote>
Notes: Reallocation invalidates all the references, pointers, and
iterators referring to the elements in the sequence. It is guaranteed
that no reallocation takes place during insertions that happen after a
call to reserve() until the time when an insertion would make the size
of the vector greater than the value of capacity() after the most
recent call to reserve().
</blockquote>
<hr>
<a name="330"><h3>330.&nbsp;Misleading &quot;exposition only&quot; value in class locale definition</h3></a><p>
<b>Section:</b>&nbsp;22.1.1 <a href="lib-locales.html#lib.locale"> [lib.locale]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Martin Sebor&nbsp; <b>Date:</b>&nbsp;15 Jul 2001</p>
<p>
The &quot;exposition only&quot; value of the std::locale::none constant shown in
the definition of class locale is misleading in that it on many
systems conflicts with the value assigned to one if the LC_XXX
constants (specifically, LC_COLLATE on AIX, LC_ALL on HP-UX, LC_CTYPE
on Linux and SunOS). This causes incorrect behavior when such a
constant is passed to one of the locale member functions that accept a
locale::category argument and interpret it as either the C LC_XXX
constant or a bitmap of locale::category values. At least three major
implementations adopt the suggested value without a change and
consequently suffer from this problem.
</p>
<p>
For instance, the following code will (presumably) incorrectly copy facets
belonging to the collate category from the German locale on AIX:
</p>
<pre>
std::locale l (std::locale (&quot;C&quot;), &quot;de_DE&quot;, std::locale::none);
</pre>
<p><b>Proposed resolution:</b></p>
<p>
Change the value from 0 to some other bit value, say 0x400, distinct
from any of the other values shown.
</p>
<hr>
<a name="331"><h3>331.&nbsp;bad declaration of destructor for ios_base::failure</h3></a><p>
<b>Section:</b>&nbsp;27.4.2.1.1 <a href="lib-iostreams.html#lib.ios::failure"> [lib.ios::failure]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;PremAnand M. Rao&nbsp; <b>Date:</b>&nbsp;23 Aug 2001</p>
<p>
With the change in 17.4.4.8 to state
&quot;An implementation may strengthen the exception-specification for a
non-virtual function by removing listed exceptions.&quot;
(issue <a href="lwg-defects.html#119">119</a>)
and the following declaration of ~failure() in ios_base::failure
</p>
<pre>
namespace std {
class ios_base::failure : public exception {
public:
...
virtual ~failure();
...
};
}
</pre>
<p>the class failure cannot be implemented since in 18.6.1 the destructor of class exception has an empty
exception specification:</p>
<pre>
namespace std {
class exception {
public:
...
virtual ~exception() throw();
...
};
}
</pre>
<p><b>Proposed resolution:</b></p>
<p>Two alternatives:</p>
<ol>
<li>Change the declaration of ~failure() to virtual ~failure() throw();</li>
<li>Remove the declaration of ~failure().</li>
</ol>
<hr>
<a name="332"><h3>332.&nbsp;Consider adding increment and decrement operators to std::fpos&lt; T &gt; </h3></a><p>
<b>Section:</b>&nbsp;27.4.3 <a href="lib-iostreams.html#lib.fpos"> [lib.fpos]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;PremAnand M. Rao&nbsp; <b>Date:</b>&nbsp;27 Aug 2001</p>
<p>
Increment and decrement operators are missing from
Table 88 -- Position type requirements in 27.4.3 .
</p>
<p><b>Proposed resolution:</b></p>
<p>
Table 88 (section 27.4.3) -- Position type requirements
be updated to include increment and decrement operators.
</p>
<pre>
expression return type operational note
++p fpos&amp; p += O(1)
p++ fpos { P tmp = p;
++p;
return tmp; }
--p fpos&amp; p -= O(1)
p-- fpos { P tmp = p;
--p;
return tmp; }
</pre>
<hr>
<a name="333"><h3>333.&nbsp;does endl imply synchronization with the device?</h3></a><p>
<b>Section:</b>&nbsp;27.6.2.7 <a href="lib-iostreams.html#lib.ostream.manip"> [lib.ostream.manip]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;PremAnand M. Rao&nbsp; <b>Date:</b>&nbsp;27 Aug 2001</p>
<p>A footnote in 27.6.2.7 states:</p>
<blockquote>
[Footnote: The effect of executing cout &lt;&lt; endl is to insert a
newline character in the output sequence controlled by cout, then
synchronize it with any external file with which it might be
associated. --- end foonote]
</blockquote>
<p>
Does the term &quot;file&quot; here refer to the external device?
This leads to some implementation ambiguity on systems with fully
buffered files where a newline does not cause a flush to the device.
</p>
<p>
Choosing to sync with the device leads to significant performance
penalties for each call to endl, while not sync-ing leads to
errors under special circumstances.
</p>
<p>
I could not find any other statement that explicitly defined
the behavior one way or the other.
</p>
<p><b>Proposed resolution:</b></p>
<hr>
<a name="334"><h3>334.&nbsp;map::operator[] specification forces inefficient implementation</h3></a><p>
<b>Section:</b>&nbsp;23.3.1.2 <a href="lib-containers.html#lib.map.access"> [lib.map.access]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Andrea Griffini&nbsp; <b>Date:</b>&nbsp;02 Sep 2001</p>
<p>
The current standard describes map::operator[] using a
code example. That code example is however quite
inefficient because it requires several useless copies
of both the passed key_type value and of default
constructed mapped_type instances.
My opinion is that was not meant by the comitee to
require all those temporary copies.
</p>
<p>Currently map::operator[] behaviour is specified as: </p>
<pre>
Returns:
(*((insert(make_pair(x, T()))).first)).second.
</pre>
<p>
This specification however uses make_pair that is a
template function of which parameters in this case
will be deduced being of type const key_type&amp; and
const T&amp;. This will create a pair&lt;key_type,T&gt; that
isn't the correct type expected by map::insert so
another copy will be required using the template
conversion constructor available in pair to build
the required pair&lt;const key_type,T&gt; instance.
</p>
<p>If we consider calling of key_type copy constructor
and mapped_type default constructor and copy
constructor as observable behaviour (as I think we
should) then the standard is in this place requiring
two copies of a key_type element plus a default
construction and two copy construction of a mapped_type
(supposing the addressed element is already present
in the map; otherwise at least another copy
construction for each type).
</p>
<p><b>Proposed resolution:</b></p>
<p>A simple (half) solution would be replacing the description with:</p>
<pre>
Returns:
(*((insert(value_type(x, T()))).first)).second.
</pre>
<p>This will remove the wrong typed pair construction that
requires one extra copy of both key and value.</p>
<p>However still the using of map::insert requires temporary
objects while the operation, from a logical point of view,
doesn't require any. </p>
<p>I think that a better solution would be leaving free an
implementer to use a different approach than map::insert
that, because of its interface, forces default constructed
temporaries and copies in this case.
The best solution in my opinion would be just requiring
map::operator[] to return a reference to the mapped_type
part of the contained element creating a default element
with the specified key if no such an element is already
present in the container. Also a logarithmic complexity
requirement should be specified for the operation.
</p>
<p>
This would allow library implementers to write alternative
implementations not using map::insert and reaching optimal
performance in both cases of the addressed element being
present or absent from the map (no temporaries at all and
just the creation of a new pair inside the container if
the element isn't present).
Some implementer has already taken this option but I think
that the current wording of the standard rules that as
non-conforming.
</p>
<p>
Note that this is a &quot;relaxing&quot; of requirment and won't
make any currently conforming implementation on this
point to become non-conforming because of the change.
</p>
<p>
There is a small risk that current code may be depending
on the number of temporaries created by map::operator[];
but I think that such dependencies would be present only
in code that is most probably already non portable as
the number of copies of parameters isn't guaranteed by
the standard (in the current wording there's just an
implicit *minimum* number of required copies).
</p>
<hr>
<a name="335"><h3>335.&nbsp;minor issue with char_traits, table 37</h3></a><p>
<b>Section:</b>&nbsp;21.1.1 <a href="lib-strings.html#lib.char.traits.require"> [lib.char.traits.require]</a>&nbsp; <b>Status:</b>&nbsp;<a href="lwg-active.html#New">New</a>&nbsp; <b>Submitter:</b>&nbsp;Andy Sawyer&nbsp; <b>Date:</b>&nbsp;06 Sep 2001</p>
<p>
Table 37, in 21.1.1 , descibes char_traits::assign
as:
</p>
<pre>
X::assign(c,d) assigns c = d.
</pre>
<p>And para 1 says:</p>
<blockquote>
[...] c and d denote values of type CharT [...]
</blockquote>
<p>
Naturally, if c and d are <i>values</i>, then the assignment is
(effectively) meaningless. It's clearly intended that (in the case of
assign, at least), 'c' is intended to be a reference type.
</p>
<p>I did a quick survey of the four implementations I happened to have
lying around, and sure enough they all have signatures:</p>
<pre>
assign( charT&amp;, const charT&amp; );
</pre>
<p>(or the equivalent). It's also described this way in Nico's book.
(Not to mention the synopses of char_traits&lt;char&gt; in 21.1.3.1
and char_traits&lt;wchar_t&gt; in 21.1.3.2...)
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following to 21.1.1 para 1:</p>
<blockquote>
r denotes a reference to CharT
</blockquote>
<p>and change the description of assign in the table to:</p>
<pre>
X::assign(r,d) assigns r = d
</pre>
<p>----- End of document -----</p>
</body>
</html>