| 1 |
20 |
jlechner |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
| 2 |
|
|
<html><head><title>C++ Standard Library Active Issues List</title></head>
|
| 3 |
|
|
|
| 4 |
|
|
<body bgcolor="#ffffff" text="#000000">
|
| 5 |
|
|
<table>
|
| 6 |
|
|
<tbody><tr>
|
| 7 |
|
|
<td align="left">Doc. no.</td>
|
| 8 |
|
|
<td align="left">N1908=05-0168</td>
|
| 9 |
|
|
</tr>
|
| 10 |
|
|
<tr>
|
| 11 |
|
|
<td align="left">Date:</td>
|
| 12 |
|
|
<td align="left">2005-10-23</td>
|
| 13 |
|
|
</tr>
|
| 14 |
|
|
<tr>
|
| 15 |
|
|
<td align="left">Project:</td>
|
| 16 |
|
|
<td align="left">Programming Language C++</td>
|
| 17 |
|
|
</tr>
|
| 18 |
|
|
<tr>
|
| 19 |
|
|
<td align="left">Reply to:</td>
|
| 20 |
|
|
<td align="left">Howard Hinnant <howard.hinnant@gmail.com></td>
|
| 21 |
|
|
</tr>
|
| 22 |
|
|
</tbody></table>
|
| 23 |
|
|
<h1>C++ Standard Library Active Issues List (Revision R39)</h1>
|
| 24 |
|
|
<p>Reference ISO/IEC IS 14882:1998(E)</p>
|
| 25 |
|
|
<p>Also see:</p>
|
| 26 |
|
|
<ul>
|
| 27 |
|
|
<li>
|
| 28 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-toc.html">Table of Contents</a> for all library issues.</li>
|
| 29 |
|
|
<li>
|
| 30 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html">Index by Section</a> for all library issues.</li>
|
| 31 |
|
|
<li>
|
| 32 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html">Index by Status</a> for all library issues.</li>
|
| 33 |
|
|
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html">Library Defect Reports List</a></li>
|
| 34 |
|
|
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html">Library Closed Issues List</a></li>
|
| 35 |
|
|
</ul>
|
| 36 |
|
|
<p>The purpose of this document is to record the status of issues
|
| 37 |
|
|
which have come before the Library Working Group (LWG) of the ANSI
|
| 38 |
|
|
(J16) and ISO (WG21) C++ Standards Committee. Issues represent
|
| 39 |
|
|
potential defects in the ISO/IEC IS 14882:1998(E) document. Issues
|
| 40 |
|
|
are not to be used to request new features. </p>
|
| 41 |
|
|
|
| 42 |
|
|
<p>This document contains only library issues which are actively being
|
| 43 |
|
|
considered by the Library Working Group. That is, issues which have a
|
| 44 |
|
|
status of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a>,
|
| 45 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a>, and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Review">Review</a>. See
|
| 46 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html">Library Defect Reports List</a> for issues considered defects and
|
| 47 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html">Library Closed Issues List</a> for issues considered closed.</p>
|
| 48 |
|
|
|
| 49 |
|
|
<p>The issues in these lists are not necessarily formal ISO Defect
|
| 50 |
|
|
Reports (DR's). While some issues will eventually be elevated to
|
| 51 |
|
|
official Defect Report status, other issues will be disposed of in
|
| 52 |
|
|
other ways. See <a href="#Status">Issue Status</a>.</p>
|
| 53 |
|
|
|
| 54 |
|
|
<p>This document is in an experimental format designed for both
|
| 55 |
|
|
viewing via a world-wide web browser and hard-copy printing. It
|
| 56 |
|
|
is available as an HTML file for browsing or PDF file for
|
| 57 |
|
|
printing.</p>
|
| 58 |
|
|
|
| 59 |
|
|
<p>Prior to Revision 14, library issues lists existed in two slightly
|
| 60 |
|
|
different versions; a Committee Version and a Public
|
| 61 |
|
|
Version. Beginning with Revision 14 the two versions were combined
|
| 62 |
|
|
into a single version.</p>
|
| 63 |
|
|
|
| 64 |
|
|
<p>This document includes <i>[bracketed italicized notes]</i> as a
|
| 65 |
|
|
reminder to the LWG of current progress on issues. Such notes are
|
| 66 |
|
|
strictly unofficial and should be read with caution as they may be
|
| 67 |
|
|
incomplete or incorrect. Be aware that LWG support for a particular
|
| 68 |
|
|
resolution can quickly change if new viewpoints or killer examples are
|
| 69 |
|
|
presented in subsequent discussions.</p>
|
| 70 |
|
|
|
| 71 |
|
|
<p>For the most current official version of this document see
|
| 72 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/">http://www.open-std.org/jtc1/sc22/wg21/</a>.
|
| 73 |
|
|
Requests for further information about this document should include
|
| 74 |
|
|
the document number above, reference ISO/IEC 14882:1998(E), and be
|
| 75 |
|
|
submitted to Information Technology Industry Council (ITI), 1250 Eye
|
| 76 |
|
|
Street NW, Washington, DC 20005.</p>
|
| 77 |
|
|
|
| 78 |
|
|
<p>Public information as to how to obtain a copy of the C++ Standard,
|
| 79 |
|
|
join the standards committee, submit an issue, or comment on an issue
|
| 80 |
|
|
can be found in the comp.std.c++ FAQ.
|
| 81 |
|
|
Public discussion of C++ Standard related issues occurs on <a href="news://comp.std.c++/">news:comp.std.c++</a>.
|
| 82 |
|
|
</p>
|
| 83 |
|
|
|
| 84 |
|
|
<p>For committee members, files available on the committee's private
|
| 85 |
|
|
web site include the HTML version of the Standard itself. HTML
|
| 86 |
|
|
hyperlinks from this issues list to those files will only work for
|
| 87 |
|
|
committee members who have downloaded them into the same disk
|
| 88 |
|
|
directory as the issues list files. </p>
|
| 89 |
|
|
<h2>Revision History</h2>
|
| 90 |
|
|
<ul>
|
| 91 |
|
|
<li>R39:
|
| 92 |
|
|
2005-10-14 post-Mont Tremblant mailing.
|
| 93 |
|
|
Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#526">526</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#528">528</a>.
|
| 94 |
|
|
Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280">280</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#461">461</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#464">464</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#465">465</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#467">467</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#468">468</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#474">474</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#496">496</a> from Ready to WP as per the vote from Mont Tremblant.
|
| 95 |
|
|
Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#247">247</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#294">294</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#342">342</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#362">362</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#369">369</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#371">371</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#376">376</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#384">384</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#475">475</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#478">478</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#495">495</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#497">497</a> from Review to Ready.
|
| 96 |
|
|
Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#498">498</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#506">506</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#509">509</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#510">510</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#511">511</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#513">513</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#514">514</a> from New to Open.
|
| 97 |
|
|
Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#505">505</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#507">507</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#508">508</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#519">519</a> from New to Ready.
|
| 98 |
|
|
Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#500">500</a> from New to NAD.
|
| 99 |
|
|
Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518">518</a> from New to Review.
|
| 100 |
|
|
</li>
|
| 101 |
|
|
<li>R38:
|
| 102 |
|
|
2005-07-03 pre-Mont Tremblant mailing.
|
| 103 |
|
|
Merged open TR1 issues in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#504">504</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#522">522</a>.
|
| 104 |
|
|
Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#523">523</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#523">523</a>
|
| 105 |
|
|
</li>
|
| 106 |
|
|
<li>R37:
|
| 107 |
|
|
2005-06 mid-term mailing.
|
| 108 |
|
|
Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#498">498</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#503">503</a>.
|
| 109 |
|
|
</li>
|
| 110 |
|
|
<li>R36:
|
| 111 |
|
|
2005-04 post-Lillehammer mailing. All issues in "ready" status except
|
| 112 |
|
|
for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#454">454</a> were moved to "DR" status, and all issues
|
| 113 |
|
|
previously in "DR" status were moved to "WP".
|
| 114 |
|
|
</li>
|
| 115 |
|
|
<li>R35:
|
| 116 |
|
|
2005-03 pre-Lillehammer mailing.
|
| 117 |
|
|
</li>
|
| 118 |
|
|
<li>R34:
|
| 119 |
|
|
2005-01 mid-term mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#488">488</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#494">494</a>.
|
| 120 |
|
|
</li>
|
| 121 |
|
|
<li>R33:
|
| 122 |
|
|
2004-11 post-Redmond mailing. Reflects actions taken in Redmond.
|
| 123 |
|
|
</li>
|
| 124 |
|
|
<li>R32:
|
| 125 |
|
|
2004-09 pre-Redmond mailing: reflects new proposed resolutions and
|
| 126 |
|
|
new issues received after the 2004-07 mailing. Added
|
| 127 |
|
|
new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#479">479</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#481">481</a>.
|
| 128 |
|
|
</li>
|
| 129 |
|
|
<li>R31:
|
| 130 |
|
|
2004-07 mid-term mailing: reflects new proposed resolutions and
|
| 131 |
|
|
new issues received after the post-Sydney mailing. Added
|
| 132 |
|
|
new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#463">463</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#478">478</a>.
|
| 133 |
|
|
</li>
|
| 134 |
|
|
<li>R30:
|
| 135 |
|
|
Post-Sydney mailing: reflects decisions made at the Sydney meeting.
|
| 136 |
|
|
Voted all "Ready" issues from R29 into the working paper.
|
| 137 |
|
|
Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#460">460</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#462">462</a>.
|
| 138 |
|
|
</li>
|
| 139 |
|
|
<li>R29:
|
| 140 |
|
|
Pre-Sydney mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#441">441</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#457">457</a>.
|
| 141 |
|
|
</li>
|
| 142 |
|
|
<li>R28:
|
| 143 |
|
|
Post-Kona mailing: reflects decisions made at the Kona meeting.
|
| 144 |
|
|
Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#432">432</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#440">440</a>.
|
| 145 |
|
|
</li>
|
| 146 |
|
|
<li>R27:
|
| 147 |
|
|
Pre-Kona mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#404">404</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#431">431</a>.
|
| 148 |
|
|
</li>
|
| 149 |
|
|
<li>R26:
|
| 150 |
|
|
Post-Oxford mailing: reflects decisions made at the Oxford meeting.
|
| 151 |
|
|
All issues in Ready status were voted into DR status. All issues in
|
| 152 |
|
|
DR status were voted into WP status.
|
| 153 |
|
|
</li>
|
| 154 |
|
|
<li>R25:
|
| 155 |
|
|
Pre-Oxford mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#390">390</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#402">402</a>.
|
| 156 |
|
|
</li>
|
| 157 |
|
|
<li>R24:
|
| 158 |
|
|
Post-Santa Cruz mailing: reflects decisions made at the Santa Cruz
|
| 159 |
|
|
meeting. All Ready issues from R23 with the exception of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#253">253</a>, which has been given a new proposed resolution, were
|
| 160 |
|
|
moved to DR status. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#383">383</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#389">389</a>. (Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#387">387</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#389">389</a> were discussed
|
| 161 |
|
|
at the meeting.) Made progress on issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a>: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a> have been moved to Ready status, and the only remaining
|
| 162 |
|
|
concerns with <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a> involve wording.
|
| 163 |
|
|
</li>
|
| 164 |
|
|
<li>R23:
|
| 165 |
|
|
Pre-Santa Cruz mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#367">367</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#382">382</a>.
|
| 166 |
|
|
Moved issues in the TC to TC status.
|
| 167 |
|
|
</li>
|
| 168 |
|
|
<li>R22:
|
| 169 |
|
|
Post-Curaçao mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#362">362</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#366">366</a>.
|
| 170 |
|
|
</li>
|
| 171 |
|
|
<li>R21:
|
| 172 |
|
|
Pre-Curaçao mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#351">351</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#361">361</a>.
|
| 173 |
|
|
</li>
|
| 174 |
|
|
<li>R20:
|
| 175 |
|
|
Post-Redmond mailing; reflects actions taken in Redmond. Added
|
| 176 |
|
|
new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#336">336</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#350">350</a>, of which issues
|
| 177 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#347">347</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#350">350</a> were added since Redmond, hence
|
| 178 |
|
|
not discussed at the meeting.
|
| 179 |
|
|
|
| 180 |
|
|
All Ready issues were moved to DR status, with the exception of issues
|
| 181 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#284">284</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241">241</a>, and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#267">267</a>.
|
| 182 |
|
|
|
| 183 |
|
|
Noteworthy issues discussed at Redmond include
|
| 184 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#120">120</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#202">202</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#233">233</a>,
|
| 185 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#270">270</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#253">253</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#254">254</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>.
|
| 186 |
|
|
</li>
|
| 187 |
|
|
<li>R19:
|
| 188 |
|
|
Pre-Redmond mailing. Added new issues
|
| 189 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#335">335</a>.
|
| 190 |
|
|
</li>
|
| 191 |
|
|
<li>R18:
|
| 192 |
|
|
Post-Copenhagen mailing; reflects actions taken in Copenhagen.
|
| 193 |
|
|
Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#312">312</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#317">317</a>, and discussed
|
| 194 |
|
|
new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#271">271</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#314">314</a>.
|
| 195 |
|
|
|
| 196 |
|
|
Changed status of issues
|
| 197 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103">103</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#118">118</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#136">136</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#153">153</a>
|
| 198 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#165">165</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#171">171</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#183">183</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#184">184</a>
|
| 199 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#185">185</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#186">186</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#214">214</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#221">221</a>
|
| 200 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#234">234</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#237">237</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#243">243</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#248">248</a>
|
| 201 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#251">251</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#252">252</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#256">256</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#260">260</a>
|
| 202 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#261">261</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#262">262</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#263">263</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#265">265</a>
|
| 203 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#268">268</a>
|
| 204 |
|
|
to DR.
|
| 205 |
|
|
|
| 206 |
|
|
Changed status of issues
|
| 207 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#49">49</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#109">109</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#117">117</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#182">182</a>
|
| 208 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#228">228</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#230">230</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#232">232</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#235">235</a>
|
| 209 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#238">238</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241">241</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#242">242</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#250">250</a>
|
| 210 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#259">259</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#264">264</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#266">266</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#267">267</a>
|
| 211 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#271">271</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#272">272</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#273">273</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#275">275</a>
|
| 212 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#281">281</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#284">284</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#285">285</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#286">286</a>
|
| 213 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#288">288</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#292">292</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#295">295</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#297">297</a>
|
| 214 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#298">298</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#301">301</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#303">303</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#306">306</a>
|
| 215 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#307">307</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#308">308</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#312">312</a>
|
| 216 |
|
|
to Ready.
|
| 217 |
|
|
|
| 218 |
|
|
Closed issues
|
| 219 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#111">111</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#277">277</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#279">279</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#287">287</a>
|
| 220 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#289">289</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#293">293</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#302">302</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#313">313</a>
|
| 221 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#314">314</a>
|
| 222 |
|
|
as NAD.
|
| 223 |
|
|
|
| 224 |
|
|
</li>
|
| 225 |
|
|
<li>R17:
|
| 226 |
|
|
Pre-Copenhagen mailing. Converted issues list to XML. Added proposed
|
| 227 |
|
|
resolutions for issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#49">49</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#76">76</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#91">91</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#235">235</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#250">250</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#267">267</a>.
|
| 228 |
|
|
Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#278">278</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#311">311</a>.
|
| 229 |
|
|
</li>
|
| 230 |
|
|
<li>R16:
|
| 231 |
|
|
post-Toronto mailing; reflects actions taken in Toronto. Added new
|
| 232 |
|
|
issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#265">265</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#277">277</a>. Changed status of issues
|
| 233 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#3">3</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#8">8</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#9">9</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#19">19</a>,
|
| 234 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#26">26</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#31">31</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#61">61</a>,
|
| 235 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#63">63</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#86">86</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#108">108</a>,
|
| 236 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#112">112</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#114">114</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#115">115</a>,
|
| 237 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#122">122</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#127">127</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#129">129</a>,
|
| 238 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#134">134</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#137">137</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#142">142</a>,
|
| 239 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#144">144</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#146">146</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#147">147</a>,
|
| 240 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#159">159</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#164">164</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#170">170</a>,
|
| 241 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#181">181</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199">199</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#208">208</a>,
|
| 242 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#209">209</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#210">210</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#211">211</a>,
|
| 243 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#212">212</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#217">217</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#220">220</a>,
|
| 244 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#222">222</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#223">223</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#224">224</a>,
|
| 245 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#227">227</a> to "DR". Reopened issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#23">23</a>. Reopened
|
| 246 |
|
|
issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#187">187</a>. Changed issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#2">2</a> and
|
| 247 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#4">4</a> to NAD. Fixed a typo in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#17">17</a>. Fixed
|
| 248 |
|
|
issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#70">70</a>: signature should be changed both places it
|
| 249 |
|
|
appears. Fixed issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#160">160</a>: previous version didn't fix
|
| 250 |
|
|
the bug in enough places.
|
| 251 |
|
|
</li>
|
| 252 |
|
|
<li>R15:
|
| 253 |
|
|
pre-Toronto mailing. Added issues
|
| 254 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#233">233</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#264">264</a>. Some small HTML formatting
|
| 255 |
|
|
changes so that we pass Weblint tests.
|
| 256 |
|
|
</li>
|
| 257 |
|
|
<li>R14:
|
| 258 |
|
|
post-Tokyo II mailing; reflects committee actions taken in
|
| 259 |
|
|
Tokyo. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#228">228</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#232">232</a>. (00-0019R1/N1242)
|
| 260 |
|
|
</li>
|
| 261 |
|
|
<li>R13:
|
| 262 |
|
|
pre-Tokyo II updated: Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#212">212</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#227">227</a>.
|
| 263 |
|
|
</li>
|
| 264 |
|
|
<li>R12:
|
| 265 |
|
|
pre-Tokyo II mailing: Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199">199</a> to
|
| 266 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#211">211</a>. Added "and paragraph 5" to the proposed resolution
|
| 267 |
|
|
of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#29">29</a>. Add further rationale to issue
|
| 268 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#178">178</a>.
|
| 269 |
|
|
</li>
|
| 270 |
|
|
<li>R11:
|
| 271 |
|
|
post-Kona mailing: Updated to reflect LWG and full committee actions
|
| 272 |
|
|
in Kona (99-0048/N1224). Note changed resolution of issues
|
| 273 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#4">4</a> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#38">38</a>. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#196">196</a>
|
| 274 |
|
|
to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#198">198</a>. Closed issues list split into "defects" and
|
| 275 |
|
|
"closed" documents. Changed the proposed resolution of issue
|
| 276 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#4">4</a> to NAD, and changed the wording of proposed resolution
|
| 277 |
|
|
of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#38">38</a>.
|
| 278 |
|
|
</li>
|
| 279 |
|
|
<li>R10:
|
| 280 |
|
|
pre-Kona updated. Added proposed resolutions <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#83">83</a>,
|
| 281 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#86">86</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#91">91</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#92">92</a>,
|
| 282 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#109">109</a>. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#190">190</a> to
|
| 283 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#195">195</a>. (99-0033/D1209, 14 Oct 99)
|
| 284 |
|
|
</li>
|
| 285 |
|
|
<li>R9:
|
| 286 |
|
|
pre-Kona mailing. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#140">140</a> to
|
| 287 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#189">189</a>. Issues list split into separate "active" and
|
| 288 |
|
|
"closed" documents. (99-0030/N1206, 25 Aug 99)
|
| 289 |
|
|
</li>
|
| 290 |
|
|
<li>R8:
|
| 291 |
|
|
post-Dublin mailing. Updated to reflect LWG and full committee actions
|
| 292 |
|
|
in Dublin. (99-0016/N1193, 21 Apr 99)
|
| 293 |
|
|
</li>
|
| 294 |
|
|
<li>R7:
|
| 295 |
|
|
pre-Dublin updated: Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">130</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#131">131</a>,
|
| 296 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#132">132</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#133">133</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#134">134</a>,
|
| 297 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#135">135</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#136">136</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#137">137</a>,
|
| 298 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#138">138</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#139">139</a> (31 Mar 99)
|
| 299 |
|
|
</li>
|
| 300 |
|
|
<li>R6:
|
| 301 |
|
|
pre-Dublin mailing. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#127">127</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#128">128</a>,
|
| 302 |
|
|
and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#129">129</a>. (99-0007/N1194, 22 Feb 99)
|
| 303 |
|
|
</li>
|
| 304 |
|
|
<li>R5:
|
| 305 |
|
|
update issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103">103</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#112">112</a>; added issues
|
| 306 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#114">114</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#126">126</a>. Format revisions to prepare
|
| 307 |
|
|
for making list public. (30 Dec 98)
|
| 308 |
|
|
</li>
|
| 309 |
|
|
<li>R4:
|
| 310 |
|
|
post-Santa Cruz II updated: Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#110">110</a>,
|
| 311 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#111">111</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#112">112</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#113">113</a> added, several
|
| 312 |
|
|
issues corrected. (22 Oct 98)
|
| 313 |
|
|
</li>
|
| 314 |
|
|
<li>R3:
|
| 315 |
|
|
post-Santa Cruz II: Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#94">94</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#109">109</a>
|
| 316 |
|
|
added, many issues updated to reflect LWG consensus (12 Oct 98)
|
| 317 |
|
|
</li>
|
| 318 |
|
|
<li>R2:
|
| 319 |
|
|
pre-Santa Cruz II: Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#73">73</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#93">93</a> added,
|
| 320 |
|
|
issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#17">17</a> updated. (29 Sep 98)
|
| 321 |
|
|
</li>
|
| 322 |
|
|
<li>R1:
|
| 323 |
|
|
Correction to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#55">55</a> resolution, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#60">60</a> code
|
| 324 |
|
|
format, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#64">64</a> title. (17 Sep 98)
|
| 325 |
|
|
</li>
|
| 326 |
|
|
</ul>
|
| 327 |
|
|
<h2>
|
| 328 |
|
|
<a name="Status"></a>Issue Status</h2>
|
| 329 |
|
|
<p><b><a name="New">New</a></b> - The issue has not yet been
|
| 330 |
|
|
reviewed by the LWG. Any <b>Proposed Resolution</b> is purely a
|
| 331 |
|
|
suggestion from the issue submitter, and should not be construed as
|
| 332 |
|
|
the view of LWG.</p>
|
| 333 |
|
|
|
| 334 |
|
|
<p><b><a name="Open">Open</a></b> - The LWG has discussed the issue
|
| 335 |
|
|
but is not yet ready to move the issue forward. There are several
|
| 336 |
|
|
possible reasons for open status:</p>
|
| 337 |
|
|
<ul>
|
| 338 |
|
|
<li>Consensus may have not yet have been reached as to how to deal
|
| 339 |
|
|
with the issue.</li>
|
| 340 |
|
|
<li>Informal consensus may have been reached, but the LWG awaits
|
| 341 |
|
|
exact <b>Proposed Resolution</b> wording for review.</li>
|
| 342 |
|
|
<li>The LWG wishes to consult additional technical experts before
|
| 343 |
|
|
proceeding.</li>
|
| 344 |
|
|
<li>The issue may require further study.</li>
|
| 345 |
|
|
</ul>
|
| 346 |
|
|
|
| 347 |
|
|
<p>A <b>Proposed Resolution</b> for an open issue is still not be
|
| 348 |
|
|
construed as the view of LWG. Comments on the current state of
|
| 349 |
|
|
discussions are often given at the end of open issues in an italic
|
| 350 |
|
|
font. Such comments are for information only and should not be given
|
| 351 |
|
|
undue importance.</p>
|
| 352 |
|
|
|
| 353 |
|
|
<p><b><a name="Dup">Dup</a></b> - The LWG has reached consensus that
|
| 354 |
|
|
the issue is a duplicate of another issue, and will not be further
|
| 355 |
|
|
dealt with. A <b>Rationale</b> identifies the duplicated issue's
|
| 356 |
|
|
issue number. </p>
|
| 357 |
|
|
|
| 358 |
|
|
<p><b><a name="NAD">NAD</a></b> - The LWG has reached consensus that
|
| 359 |
|
|
the issue is not a defect in the Standard, and the issue is ready to
|
| 360 |
|
|
forward to the full committee as a proposed record of response. A
|
| 361 |
|
|
<b>Rationale</b> discusses the LWG's reasoning.</p>
|
| 362 |
|
|
|
| 363 |
|
|
<p><b><a name="Review">Review</a></b> - Exact wording of a
|
| 364 |
|
|
<b>Proposed Resolution</b> is now available for review on an issue
|
| 365 |
|
|
for which the LWG previously reached informal consensus.</p>
|
| 366 |
|
|
|
| 367 |
|
|
<p><b><a name="Ready">Ready</a></b> - The LWG has reached consensus
|
| 368 |
|
|
that the issue is a defect in the Standard, the <b>Proposed
|
| 369 |
|
|
Resolution</b> is correct, and the issue is ready to forward to the
|
| 370 |
|
|
full committee for further action as a Defect Report (DR).</p>
|
| 371 |
|
|
|
| 372 |
|
|
<p><b><a name="DR">DR</a></b> - (Defect Report) - The full J16
|
| 373 |
|
|
committee has voted to forward the issue to the Project Editor to be
|
| 374 |
|
|
processed as a Potential Defect Report. The Project Editor reviews
|
| 375 |
|
|
the issue, and then forwards it to the WG21 Convenor, who returns it
|
| 376 |
|
|
to the full committee for final disposition. This issues list
|
| 377 |
|
|
accords the status of DR to all these Defect Reports regardless of
|
| 378 |
|
|
where they are in that process.</p>
|
| 379 |
|
|
|
| 380 |
|
|
<p><b><a name="TC">TC</a></b> - (Technical Corrigenda) - The full
|
| 381 |
|
|
WG21 committee has voted to accept the Defect Report's Proposed
|
| 382 |
|
|
Resolution as a Technical Corrigenda. Action on this issue is thus
|
| 383 |
|
|
complete and no further action is possible under ISO rules.</p>
|
| 384 |
|
|
|
| 385 |
|
|
<p><b><a name="WP">WP</a></b> - (Working Paper) - The proposed
|
| 386 |
|
|
resolution has not been accepted as a Technical Corrigendum, but
|
| 387 |
|
|
the full WG21 committee has voted to apply the Defect Report's Proposed
|
| 388 |
|
|
Resolution to the working paper.</p>
|
| 389 |
|
|
|
| 390 |
|
|
<p><b><a name="RR">RR</a></b> - (Record of Response) - The full WG21
|
| 391 |
|
|
committee has determined that this issue is not a defect in the
|
| 392 |
|
|
Standard. Action on this issue is thus complete and no further
|
| 393 |
|
|
action is possible under ISO rules.</p>
|
| 394 |
|
|
|
| 395 |
|
|
<p><b><a name="Future">Future</a></b> - In addition to the regular
|
| 396 |
|
|
status, the LWG believes that this issue should be revisited at the
|
| 397 |
|
|
next revision of the standard. It is usually paired with NAD.</p>
|
| 398 |
|
|
|
| 399 |
|
|
<p>Issues are always given the status of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> when
|
| 400 |
|
|
they first appear on the issues list. They may progress to
|
| 401 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> or <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Review">Review</a> while the LWG
|
| 402 |
|
|
is actively working on them. When the LWG has reached consensus on
|
| 403 |
|
|
the disposition of an issue, the status will then change to
|
| 404 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Dup">Dup</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#NAD">NAD</a>, or <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> as appropriate. Once the full J16 committee votes to
|
| 405 |
|
|
forward Ready issues to the Project Editor, they are given the
|
| 406 |
|
|
status of Defect Report ( <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a>). These in turn may
|
| 407 |
|
|
become the basis for Technical Corrigenda (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a>),
|
| 408 |
|
|
or are closed without action other than a Record of Response
|
| 409 |
|
|
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#RR">RR</a> ). The intent of this LWG process is that
|
| 410 |
|
|
only issues which are truly defects in the Standard move to the
|
| 411 |
|
|
formal ISO DR status.
|
| 412 |
|
|
</p>
|
| 413 |
|
|
|
| 414 |
|
|
<h2>Active Issues</h2>
|
| 415 |
|
|
<hr>
|
| 416 |
|
|
<a name="23"><h3>23. Num_get overflow result</h3></a><p><b>Section:</b> 22.2.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p>
|
| 417 |
|
|
<p>The current description of numeric input does not account for the
|
| 418 |
|
|
possibility of overflow. This is an implicit result of changing the
|
| 419 |
|
|
description to rely on the definition of scanf() (which fails to
|
| 420 |
|
|
report overflow), and conflicts with the documented behavior of
|
| 421 |
|
|
traditional and current implementations. </p>
|
| 422 |
|
|
|
| 423 |
|
|
<p>Users expect, when reading a character sequence that results in a
|
| 424 |
|
|
value unrepresentable in the specified type, to have an error
|
| 425 |
|
|
reported. The standard as written does not permit this. </p>
|
| 426 |
|
|
|
| 427 |
|
|
<p><b>Further comments from Dietmar:</b></p>
|
| 428 |
|
|
|
| 429 |
|
|
<p>
|
| 430 |
|
|
I don't feel comfortable with the proposed resolution to issue 23: It
|
| 431 |
|
|
kind of simplifies the issue to much. Here is what is going on:
|
| 432 |
|
|
</p>
|
| 433 |
|
|
|
| 434 |
|
|
<p>
|
| 435 |
|
|
Currently, the behavior of numeric overflow is rather counter intuitive
|
| 436 |
|
|
and hard to trace, so I will describe it briefly:
|
| 437 |
|
|
</p>
|
| 438 |
|
|
|
| 439 |
|
|
<ul>
|
| 440 |
|
|
<li>
|
| 441 |
|
|
According to 22.2.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a>
|
| 442 |
|
|
paragraph 11 <tt>failbit</tt> is set if <tt>scanf()</tt> would
|
| 443 |
|
|
return an input error; otherwise a value is converted to the rules
|
| 444 |
|
|
of <tt>scanf</tt>.
|
| 445 |
|
|
</li>
|
| 446 |
|
|
<li>
|
| 447 |
|
|
<tt>scanf()</tt> is defined in terms of <tt>fscanf()</tt>.
|
| 448 |
|
|
</li>
|
| 449 |
|
|
<li>
|
| 450 |
|
|
<tt>fscanf()</tt> returns an input failure if during conversion no
|
| 451 |
|
|
character matching the conversion specification could be extracted
|
| 452 |
|
|
before reaching EOF. This is the only reason for <tt>fscanf()</tt>
|
| 453 |
|
|
to fail due to an input error and clearly does not apply to the case
|
| 454 |
|
|
of overflow.
|
| 455 |
|
|
</li>
|
| 456 |
|
|
<li>
|
| 457 |
|
|
Thus, the conversion is performed according to the rules of
|
| 458 |
|
|
<tt>fscanf()</tt> which basically says that <tt>strtod</tt>,
|
| 459 |
|
|
<tt>strtol()</tt>, etc. are to be used for the conversion.
|
| 460 |
|
|
</li>
|
| 461 |
|
|
<li>
|
| 462 |
|
|
The <tt>strtod()</tt>, <tt>strtol()</tt>, etc. functions consume as
|
| 463 |
|
|
many matching characters as there are and on overflow continue to
|
| 464 |
|
|
consume matching characters but also return a value identical to
|
| 465 |
|
|
the maximum (or minimum for signed types if there was a leading minus)
|
| 466 |
|
|
value of the corresponding type and set <tt>errno</tt> to <tt>ERANGE</tt>.
|
| 467 |
|
|
</li>
|
| 468 |
|
|
<li>
|
| 469 |
|
|
Thus, according to the current wording in the standard, overflows
|
| 470 |
|
|
can be detected! All what is to be done is to check <tt>errno</tt>
|
| 471 |
|
|
after reading an element and, of course, clearing <tt>errno</tt>
|
| 472 |
|
|
before trying a conversion. With the current wording, it can be
|
| 473 |
|
|
detected whether the overflow was due to a positive or negative
|
| 474 |
|
|
number for signed types.
|
| 475 |
|
|
</li>
|
| 476 |
|
|
</ul>
|
| 477 |
|
|
|
| 478 |
|
|
<p><b>Further discussion from Redmond:</b></p>
|
| 479 |
|
|
|
| 480 |
|
|
<p>The basic problem is that we've defined our behavior,
|
| 481 |
|
|
including our error-reporting behavior, in terms of C90. However,
|
| 482 |
|
|
C90's method of reporting overflow in scanf is not technically an
|
| 483 |
|
|
"input error". The <tt>strto_*</tt> functions are more precise.</p>
|
| 484 |
|
|
|
| 485 |
|
|
<p>There was general consensus that <tt>failbit</tt> should be set
|
| 486 |
|
|
upon overflow. We considered three options based on this:</p>
|
| 487 |
|
|
<ol>
|
| 488 |
|
|
<li>Set failbit upon conversion error (including overflow), and
|
| 489 |
|
|
don't store any value.</li>
|
| 490 |
|
|
<li>Set failbit upon conversion error, and also set <tt>errno</tt> to
|
| 491 |
|
|
indicated the precise nature of the error.</li>
|
| 492 |
|
|
<li>Set failbit upon conversion error. If the error was due to
|
| 493 |
|
|
overflow, store +-numeric_limits<T>::max() as an
|
| 494 |
|
|
overflow indication.</li>
|
| 495 |
|
|
</ol>
|
| 496 |
|
|
|
| 497 |
|
|
<p>Straw poll: (1) 5; (2) 0; (3) 8.</p>
|
| 498 |
|
|
|
| 499 |
|
|
|
| 500 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 501 |
|
|
|
| 502 |
|
|
<p>Discussed at Lillehammer. General outline of what we want the
|
| 503 |
|
|
solution to look like: we want to say that overflow is an error, and
|
| 504 |
|
|
provide a way to distinguish overflow from other kinds of errors.
|
| 505 |
|
|
Choose candidate field the same way scanf does, but don't describe
|
| 506 |
|
|
the rest of the process in terms of format. If a finite input field
|
| 507 |
|
|
is too large (positive or negative) to be represented as a finite
|
| 508 |
|
|
value, then set failbit and assign the nearest representable value.
|
| 509 |
|
|
Bill will provide wording.</p>
|
| 510 |
|
|
|
| 511 |
|
|
<hr>
|
| 512 |
|
|
<a name="96"><h3>96. Vector<bool> is not a container</h3></a><p><b>Section:</b> 23.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.vector.bool"> [lib.vector.bool]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> AFNOR <b>Date:</b> 7 Oct 1998</p>
|
| 513 |
|
|
<p><tt>vector<bool></tt> is not a container as its reference and
|
| 514 |
|
|
pointer types are not references and pointers. </p>
|
| 515 |
|
|
|
| 516 |
|
|
<p>Also it forces everyone to have a space optimization instead of a
|
| 517 |
|
|
speed one.</p>
|
| 518 |
|
|
|
| 519 |
|
|
<p><b>See also:</b> 99-0008 == N1185 Vector<bool> is
|
| 520 |
|
|
Nonconforming, Forces Optimization Choice.</p>
|
| 521 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 522 |
|
|
|
| 523 |
|
|
<p><i>[In Santa Cruz the LWG felt that this was Not A Defect.]</i></p>
|
| 524 |
|
|
|
| 525 |
|
|
<p><i>[In Dublin many present felt that failure to meet Container
|
| 526 |
|
|
requirements was a defect. There was disagreement as to whether
|
| 527 |
|
|
or not the optimization requirements constituted a defect.]</i></p>
|
| 528 |
|
|
|
| 529 |
|
|
<p><i>[The LWG looked at the following resolutions in some detail:
|
| 530 |
|
|
<br>
|
| 531 |
|
|
* Not A Defect.<br>
|
| 532 |
|
|
* Add a note explaining that vector<bool> does not meet
|
| 533 |
|
|
Container requirements.<br>
|
| 534 |
|
|
* Remove vector<bool>.<br>
|
| 535 |
|
|
* Add a new category of container requirements which
|
| 536 |
|
|
vector<bool> would meet.<br>
|
| 537 |
|
|
* Rename vector<bool>.<br>
|
| 538 |
|
|
<br>
|
| 539 |
|
|
No alternative had strong, wide-spread, support and every alternative
|
| 540 |
|
|
had at least one "over my dead body" response.<br>
|
| 541 |
|
|
<br>
|
| 542 |
|
|
There was also mention of a transition scheme something like (1) add
|
| 543 |
|
|
vector_bool and deprecate vector<bool> in the next standard. (2)
|
| 544 |
|
|
Remove vector<bool> in the following standard.]</i></p>
|
| 545 |
|
|
|
| 546 |
|
|
<p><i>[Modifying container requirements to permit returning proxies
|
| 547 |
|
|
(thus allowing container requirements conforming vector<bool>)
|
| 548 |
|
|
was also discussed.]</i></p>
|
| 549 |
|
|
|
| 550 |
|
|
<p><i>[It was also noted that there is a partial but ugly workaround in
|
| 551 |
|
|
that vector<bool> may be further specialized with a customer
|
| 552 |
|
|
allocator.]</i></p>
|
| 553 |
|
|
|
| 554 |
|
|
<p><i>[Kona: Herb Sutter presented his paper J16/99-0035==WG21/N1211,
|
| 555 |
|
|
vector<bool>: More Problems, Better Solutions. Much discussion
|
| 556 |
|
|
of a two step approach: a) deprecate, b) provide replacement under a
|
| 557 |
|
|
new name. LWG straw vote on that: 1-favor, 11-could live with, 2-over
|
| 558 |
|
|
my dead body. This resolution was mentioned in the LWG report to the
|
| 559 |
|
|
full committee, where several additional committee members indicated
|
| 560 |
|
|
over-my-dead-body positions.]</i></p>
|
| 561 |
|
|
|
| 562 |
|
|
<p>Discussed at Lillehammer. General agreement that we should
|
| 563 |
|
|
deprecate vector<bool> and introduce this functionality under
|
| 564 |
|
|
a different name, e.g. bit_vector. This might make it possible to
|
| 565 |
|
|
remove the vector<bool> specialization in the standard that comes
|
| 566 |
|
|
after C++0x. There was also a suggestion that
|
| 567 |
|
|
in C++0x we could additional say that it's implementation defined
|
| 568 |
|
|
whether vector<bool> refers to the specialization or to the
|
| 569 |
|
|
primary template, but there wasn't general agreement that this was a
|
| 570 |
|
|
good idea.</p>
|
| 571 |
|
|
|
| 572 |
|
|
<p>We need a paper for the new bit_vector class.</p>
|
| 573 |
|
|
|
| 574 |
|
|
<hr>
|
| 575 |
|
|
<a name="201"><h3>201. Numeric limits terminology wrong</h3></a><p><b>Section:</b> 18.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.limits"> [lib.limits]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Stephen Cleary <b>Date:</b> 21 Dec 1999</p>
|
| 576 |
|
|
<p>
|
| 577 |
|
|
In some places in this section, the terms "fundamental types" and
|
| 578 |
|
|
"scalar types" are used when the term "arithmetic types" is intended.
|
| 579 |
|
|
The current usage is incorrect because void is a fundamental type and
|
| 580 |
|
|
pointers are scalar types, neither of which should have
|
| 581 |
|
|
specializations of numeric_limits.
|
| 582 |
|
|
</p>
|
| 583 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 584 |
|
|
<p><i>[Lillehammer: it remains true that numeric_limits is using
|
| 585 |
|
|
imprecise language. However, none of the proposals for changed
|
| 586 |
|
|
wording are clearer. A redesign of numeric_limits is needed, but this
|
| 587 |
|
|
is more a task than an open issue.]</i></p>
|
| 588 |
|
|
<hr>
|
| 589 |
|
|
<a name="233"><h3>233. Insertion hints in associative containers</h3></a><p><b>Section:</b> 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 30 Apr 2000</p>
|
| 590 |
|
|
<p>
|
| 591 |
|
|
If <tt>mm</tt> is a multimap and <tt>p</tt> is an iterator
|
| 592 |
|
|
into the multimap, then <tt>mm.insert(p, x)</tt> inserts
|
| 593 |
|
|
<tt>x</tt> into <tt>mm</tt> with <tt>p</tt> as a hint as
|
| 594 |
|
|
to where it should go. Table 69 claims that the execution time is
|
| 595 |
|
|
amortized constant if the insert winds up taking place adjacent to
|
| 596 |
|
|
<tt>p</tt>, but does not say when, if ever, this is guaranteed to
|
| 597 |
|
|
happen. All it says it that <tt>p</tt> is a hint as to where to
|
| 598 |
|
|
insert.
|
| 599 |
|
|
</p>
|
| 600 |
|
|
<p>
|
| 601 |
|
|
The question is whether there is any guarantee about the relationship
|
| 602 |
|
|
between <tt>p</tt> and the insertion point, and, if so, what it
|
| 603 |
|
|
is.
|
| 604 |
|
|
</p>
|
| 605 |
|
|
<p>
|
| 606 |
|
|
I believe the present state is that there is no guarantee: The user
|
| 607 |
|
|
can supply <tt>p</tt>, and the implementation is allowed to
|
| 608 |
|
|
disregard it entirely.
|
| 609 |
|
|
</p>
|
| 610 |
|
|
|
| 611 |
|
|
<p><b>Additional comments from Nathan:</b><br>
|
| 612 |
|
|
|
| 613 |
|
|
The vote [in Redmond] was on whether to elaborately specify the use of
|
| 614 |
|
|
the hint, or to require behavior only if the value could be inserted
|
| 615 |
|
|
adjacent to the hint. I would like to ensure that we have a chance to
|
| 616 |
|
|
vote for a deterministic treatment: "before, if possible, otherwise
|
| 617 |
|
|
after, otherwise anywhere appropriate", as an alternative to the
|
| 618 |
|
|
proposed "before or after, if possible, otherwise [...]".
|
| 619 |
|
|
</p>
|
| 620 |
|
|
|
| 621 |
|
|
|
| 622 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 623 |
|
|
|
| 624 |
|
|
<p>In table 69 "Associative Container Requirements" in 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a>, in the row for <tt>a.insert(p, t)</tt>,
|
| 625 |
|
|
change</p>
|
| 626 |
|
|
|
| 627 |
|
|
<blockquote>
|
| 628 |
|
|
iterator p is a hint pointing to where the insert
|
| 629 |
|
|
should start to search.
|
| 630 |
|
|
</blockquote>
|
| 631 |
|
|
|
| 632 |
|
|
<p>to</p>
|
| 633 |
|
|
|
| 634 |
|
|
<blockquote>
|
| 635 |
|
|
insertion adjacent to iterator p is preferred if
|
| 636 |
|
|
more than one insertion point is valid.
|
| 637 |
|
|
</blockquote>
|
| 638 |
|
|
|
| 639 |
|
|
<p>and change</p>
|
| 640 |
|
|
|
| 641 |
|
|
<blockquote>
|
| 642 |
|
|
logarithmic in general, but amortized constant if
|
| 643 |
|
|
t is inserted right after p.
|
| 644 |
|
|
</blockquote>
|
| 645 |
|
|
|
| 646 |
|
|
<p>to</p>
|
| 647 |
|
|
|
| 648 |
|
|
<blockquote>
|
| 649 |
|
|
logarithmic in general, but amortized constant if
|
| 650 |
|
|
t is inserted adjacent to iterator p.
|
| 651 |
|
|
</blockquote>
|
| 652 |
|
|
|
| 653 |
|
|
<p><i>[Toronto: there was general agreement that this is a real defect:
|
| 654 |
|
|
when inserting an element x into a multiset that already contains
|
| 655 |
|
|
several copies of x, there is no way to know whether the hint will be
|
| 656 |
|
|
used. The proposed resolution was that the new element should always
|
| 657 |
|
|
be inserted as close to the hint as possible. So, for example, if
|
| 658 |
|
|
there is a subsequence of equivalent values, then providing a.begin()
|
| 659 |
|
|
as the hint means that the new element should be inserted before the
|
| 660 |
|
|
subsequence even if a.begin() is far away. JC van Winkel supplied
|
| 661 |
|
|
precise wording for this proposed resolution, and also for an
|
| 662 |
|
|
alternative resolution in which hints are only used when they are
|
| 663 |
|
|
adjacent to the insertion point.]</i></p>
|
| 664 |
|
|
|
| 665 |
|
|
<p><i>[Copenhagen: the LWG agreed to the original proposed resolution,
|
| 666 |
|
|
in which an insertion hint would be used even when it is far from the
|
| 667 |
|
|
insertion point. This was contingent on seeing a reference
|
| 668 |
|
|
implementation showing that it is possible to implement this
|
| 669 |
|
|
requirement without loss of efficiency. John Potter provided such a
|
| 670 |
|
|
reference implementation.]</i></p>
|
| 671 |
|
|
|
| 672 |
|
|
<p><i>[Redmond: The LWG was reluctant to adopt the proposal that
|
| 673 |
|
|
emerged from Copenhagen: it seemed excessively complicated, and went
|
| 674 |
|
|
beyond fixing the defect that we identified in Toronto. PJP provided
|
| 675 |
|
|
the new wording described in this issue. Nathan agrees that we
|
| 676 |
|
|
shouldn't adopt the more detailed semantics, and notes: "we know that
|
| 677 |
|
|
you can do it efficiently enough with a red-black tree, but there are
|
| 678 |
|
|
other (perhaps better) balanced tree techniques that might differ
|
| 679 |
|
|
enough to make the detailed semantics hard to satisfy."]</i></p>
|
| 680 |
|
|
|
| 681 |
|
|
<p><i>[Curaçao: Nathan should give us the alternative wording he
|
| 682 |
|
|
suggests so the LWG can decide between the two options.]</i></p>
|
| 683 |
|
|
|
| 684 |
|
|
<p><i>[Lillehammer: The LWG previously rejected the more detailed
|
| 685 |
|
|
semantics, because it seemed more loike a new feature than like
|
| 686 |
|
|
defect fixing. We're now more sympathetic to it, but we (especially
|
| 687 |
|
|
Bill) are still worried about performance. N1780 describes a naive
|
| 688 |
|
|
algorithm, but it's not clear whether there is a non-naive
|
| 689 |
|
|
implementation. Is it possible to implement this as efficently as
|
| 690 |
|
|
the current version of insert?]</i></p>
|
| 691 |
|
|
|
| 692 |
|
|
<p><i>[Post Lillehammer: N1780 updated in post meeting mailing with
|
| 693 |
|
|
feedback from Lillehammer with more information regarding performance.
|
| 694 |
|
|
]</i></p>
|
| 695 |
|
|
|
| 696 |
|
|
<hr>
|
| 697 |
|
|
<a name="247"><h3>247. <tt>vector</tt>, <tt>deque::insert</tt> complexity</h3></a><p><b>Section:</b> 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.vector.modifiers"> [lib.vector.modifiers]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Lisa Lippincott <b>Date:</b> 06 June 2000</p>
|
| 698 |
|
|
<p>Paragraph 2 of 23.2.4.3 [lib.vector.modifiers] describes the complexity
|
| 699 |
|
|
of <tt>vector::insert</tt>:</p>
|
| 700 |
|
|
|
| 701 |
|
|
<blockquote>
|
| 702 |
|
|
Complexity: If first and last are forward iterators, bidirectional
|
| 703 |
|
|
iterators, or random access iterators, the complexity is linear in
|
| 704 |
|
|
the number of elements in the range [first, last) plus the distance
|
| 705 |
|
|
to the end of the vector. If they are input iterators, the complexity
|
| 706 |
|
|
is proportional to the number of elements in the range [first, last)
|
| 707 |
|
|
times the distance to the end of the vector.
|
| 708 |
|
|
</blockquote>
|
| 709 |
|
|
|
| 710 |
|
|
<p>First, this fails to address the non-iterator forms of
|
| 711 |
|
|
<tt>insert</tt>.</p>
|
| 712 |
|
|
|
| 713 |
|
|
<p>Second, the complexity for input iterators misses an edge case --
|
| 714 |
|
|
it requires that an arbitrary number of elements can be added at
|
| 715 |
|
|
the end of a <tt>vector</tt> in constant time.</p>
|
| 716 |
|
|
|
| 717 |
|
|
<p>I looked to see if <tt>deque</tt> had a similar problem, and was
|
| 718 |
|
|
surprised to find that <tt>deque</tt> places no requirement on the
|
| 719 |
|
|
complexity of inserting multiple elements (23.2.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.modifiers"> [lib.deque.modifiers]</a>,
|
| 720 |
|
|
paragraph 3):</p>
|
| 721 |
|
|
|
| 722 |
|
|
<blockquote>
|
| 723 |
|
|
Complexity: In the worst case, inserting a single element into a
|
| 724 |
|
|
deque takes time linear in the minimum of the distance from the
|
| 725 |
|
|
insertion point to the beginning of the deque and the distance
|
| 726 |
|
|
from the insertion point to the end of the deque. Inserting a
|
| 727 |
|
|
single element either at the beginning or end of a deque always
|
| 728 |
|
|
takes constant time and causes a single call to the copy constructor
|
| 729 |
|
|
of T.
|
| 730 |
|
|
</blockquote>
|
| 731 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 732 |
|
|
|
| 733 |
|
|
<p>Change Paragraph 2 of 23.2.4.3 [lib.vector.modifiers] to</p>
|
| 734 |
|
|
<blockquote>
|
| 735 |
|
|
Complexity: The complexity is linear in the number of elements
|
| 736 |
|
|
inserted plus the distance to the end of the vector.
|
| 737 |
|
|
</blockquote>
|
| 738 |
|
|
|
| 739 |
|
|
<p><i>[For input iterators, one may achieve this complexity by first
|
| 740 |
|
|
inserting at the end of the <tt>vector</tt>, and then using
|
| 741 |
|
|
<tt>rotate</tt>.]</i></p>
|
| 742 |
|
|
|
| 743 |
|
|
<p>Change 23.2.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.modifiers"> [lib.deque.modifiers]</a>, paragraph 3, to:</p>
|
| 744 |
|
|
|
| 745 |
|
|
<blockquote>
|
| 746 |
|
|
Complexity: The complexity is linear in the number of elements
|
| 747 |
|
|
inserted plus the shorter of the distances to the beginning and
|
| 748 |
|
|
end of the deque. Inserting a single element at either the
|
| 749 |
|
|
beginning or the end of a deque causes a single call to the copy
|
| 750 |
|
|
constructor of T.
|
| 751 |
|
|
</blockquote>
|
| 752 |
|
|
|
| 753 |
|
|
<p><b>Rationale:</b></p>
|
| 754 |
|
|
<p>This is a real defect, and proposed resolution fixes it: some
|
| 755 |
|
|
complexities aren't specified that should be. This proposed
|
| 756 |
|
|
resolution does constrain deque implementations (it rules out the
|
| 757 |
|
|
most naive possible implementations), but the LWG doesn't see a
|
| 758 |
|
|
reason to permit that implementation.</p>
|
| 759 |
|
|
<hr>
|
| 760 |
|
|
<a name="254"><h3>254. Exception types in clause 19 are constructed from <tt>std::string</tt>
|
| 761 |
|
|
</h3></a><p><b>Section:</b> 19.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-diagnostics.html#lib.std.exceptions"> [lib.std.exceptions]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 01 Aug 2000</p>
|
| 762 |
|
|
<p>
|
| 763 |
|
|
Many of the standard exception types which implementations are
|
| 764 |
|
|
required to throw are constructed with a const std::string&
|
| 765 |
|
|
parameter. For example:
|
| 766 |
|
|
</p>
|
| 767 |
|
|
|
| 768 |
|
|
<pre> 19.1.5 Class out_of_range [lib.out.of.range]
|
| 769 |
|
|
namespace std {
|
| 770 |
|
|
class out_of_range : public logic_error {
|
| 771 |
|
|
public:
|
| 772 |
|
|
explicit out_of_range(const string& what_arg);
|
| 773 |
|
|
};
|
| 774 |
|
|
}
|
| 775 |
|
|
|
| 776 |
|
|
1 The class out_of_range defines the type of objects thrown as excep-
|
| 777 |
|
|
tions to report an argument value not in its expected range.
|
| 778 |
|
|
|
| 779 |
|
|
out_of_range(const string& what_arg);
|
| 780 |
|
|
|
| 781 |
|
|
Effects:
|
| 782 |
|
|
Constructs an object of class out_of_range.
|
| 783 |
|
|
Postcondition:
|
| 784 |
|
|
strcmp(what(), what_arg.c_str()) == 0.
|
| 785 |
|
|
</pre>
|
| 786 |
|
|
|
| 787 |
|
|
<p>
|
| 788 |
|
|
There are at least two problems with this:
|
| 789 |
|
|
</p>
|
| 790 |
|
|
<ol>
|
| 791 |
|
|
<li>A program which is low on memory may end up throwing
|
| 792 |
|
|
std::bad_alloc instead of out_of_range because memory runs out while
|
| 793 |
|
|
constructing the exception object.</li>
|
| 794 |
|
|
<li>An obvious implementation which stores a std::string data member
|
| 795 |
|
|
may end up invoking terminate() during exception unwinding because the
|
| 796 |
|
|
exception object allocates memory (or rather fails to) as it is being
|
| 797 |
|
|
copied.</li>
|
| 798 |
|
|
</ol>
|
| 799 |
|
|
|
| 800 |
|
|
<p>
|
| 801 |
|
|
There may be no cure for (1) other than changing the interface to
|
| 802 |
|
|
out_of_range, though one could reasonably argue that (1) is not a
|
| 803 |
|
|
defect. Personally I don't care that much if out-of-memory is reported
|
| 804 |
|
|
when I only have 20 bytes left, in the case when out_of_range would
|
| 805 |
|
|
have been reported. People who use exception-specifications might care
|
| 806 |
|
|
a lot, though.
|
| 807 |
|
|
</p>
|
| 808 |
|
|
|
| 809 |
|
|
<p>
|
| 810 |
|
|
There is a cure for (2), but it isn't completely obvious. I think a
|
| 811 |
|
|
note for implementors should be made in the standard. Avoiding
|
| 812 |
|
|
possible termination in this case shouldn't be left up to chance. The
|
| 813 |
|
|
cure is to use a reference-counted "string" implementation
|
| 814 |
|
|
in the exception object. I am not necessarily referring to a
|
| 815 |
|
|
std::string here; any simple reference-counting scheme for a NTBS
|
| 816 |
|
|
would do.
|
| 817 |
|
|
</p>
|
| 818 |
|
|
|
| 819 |
|
|
<p><b>Further discussion, in email:</b></p>
|
| 820 |
|
|
|
| 821 |
|
|
<p>
|
| 822 |
|
|
...I'm not so concerned about (1). After all, a library implementation
|
| 823 |
|
|
can add const char* constructors as an extension, and users don't
|
| 824 |
|
|
<i>need</i> to avail themselves of the standard exceptions, though this is
|
| 825 |
|
|
a lame position to be forced into. FWIW, std::exception and
|
| 826 |
|
|
std::bad_alloc don't require a temporary basic_string.
|
| 827 |
|
|
</p>
|
| 828 |
|
|
|
| 829 |
|
|
<p>
|
| 830 |
|
|
...I don't think the fixed-size buffer is a solution to the problem,
|
| 831 |
|
|
strictly speaking, because you can't satisfy the postcondition
|
| 832 |
|
|
<br>
|
| 833 |
|
|
<tt> strcmp(what(), what_arg.c_str()) == 0</tt>
|
| 834 |
|
|
<br>
|
| 835 |
|
|
For all values of what_arg (i.e. very long values). That means that
|
| 836 |
|
|
the only truly conforming solution requires a dynamic allocation.
|
| 837 |
|
|
</p>
|
| 838 |
|
|
|
| 839 |
|
|
<p><b>Further discussion, from Redmond:</b></p>
|
| 840 |
|
|
|
| 841 |
|
|
<p>The most important progress we made at the Redmond meeting was
|
| 842 |
|
|
realizing that there are two separable issues here: the const
|
| 843 |
|
|
string& constructor, and the copy constructor. If a user writes
|
| 844 |
|
|
something like <tt>throw std::out_of_range("foo")</tt>, the const
|
| 845 |
|
|
string& constructor is invoked before anything gets thrown. The
|
| 846 |
|
|
copy constructor is potentially invoked during stack unwinding.</p>
|
| 847 |
|
|
|
| 848 |
|
|
<p>The copy constructor is a more serious problem, becuase failure
|
| 849 |
|
|
during stack unwinding invokes <tt>terminate</tt>. The copy
|
| 850 |
|
|
constructor must be nothrow. <i>Curaçao: Howard thinks this
|
| 851 |
|
|
requirement may already be present.</i></p>
|
| 852 |
|
|
|
| 853 |
|
|
<p>The fundamental problem is that it's difficult to get the nothrow
|
| 854 |
|
|
requirement to work well with the requirement that the exception
|
| 855 |
|
|
objects store a string of unbounded size, particularly if you also try
|
| 856 |
|
|
to make the const string& constructor nothrow. Options discussed
|
| 857 |
|
|
include:</p>
|
| 858 |
|
|
|
| 859 |
|
|
<ul>
|
| 860 |
|
|
<li>Limit the size of a string that exception objects are required to
|
| 861 |
|
|
throw: change the postconditions of 19.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-diagnostics.html#lib.domain.error"> [lib.domain.error]</a> paragraph 3
|
| 862 |
|
|
and 19.1.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-diagnostics.html#lib.runtime.error"> [lib.runtime.error]</a> paragraph 3 to something like this:
|
| 863 |
|
|
"strncmp(what(), what_arg._str(), N) == 0, where N is an
|
| 864 |
|
|
implementation defined constant no smaller than 256".</li>
|
| 865 |
|
|
<li>Allow the const string& constructor to throw, but not the
|
| 866 |
|
|
copy constructor. It's the implementor's responsibility to get it
|
| 867 |
|
|
right. (An implementor might use a simple refcount class.)</li>
|
| 868 |
|
|
<li>Compromise between the two: an implementation is not allowed to
|
| 869 |
|
|
throw if the string's length is less than some N, but, if it doesn't
|
| 870 |
|
|
throw, the string must compare equal to the argument.</li>
|
| 871 |
|
|
<li>Add a new constructor that takes a const char*</li>
|
| 872 |
|
|
</ul>
|
| 873 |
|
|
|
| 874 |
|
|
<p>(Not all of these options are mutually exclusive.)</p>
|
| 875 |
|
|
|
| 876 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 877 |
|
|
<p><b>Rationale:</b></p>
|
| 878 |
|
|
|
| 879 |
|
|
<p>Throwing a bad_alloc while trying to construct a message for another
|
| 880 |
|
|
exception-derived class is not necessarily a bad thing. And the
|
| 881 |
|
|
bad_alloc constructor already has a no throw spec on it (18.4.2.1).</p>
|
| 882 |
|
|
|
| 883 |
|
|
<p><b>Future:</b></p>
|
| 884 |
|
|
|
| 885 |
|
|
<p>All involved would like to see const char* constructors added, but
|
| 886 |
|
|
this should probably be done for C++0X as opposed to a DR.</p>
|
| 887 |
|
|
|
| 888 |
|
|
<p>I believe the no throw specs currently decorating these functions
|
| 889 |
|
|
could be improved by some kind of static no throw spec checking
|
| 890 |
|
|
mechanism (in a future C++ language). As they stand, the copy
|
| 891 |
|
|
constructors might fail via a call to unexpected. I think what is
|
| 892 |
|
|
intended here is that the copy constructors can't fail.</p>
|
| 893 |
|
|
|
| 894 |
|
|
<p><i>[Pre-Sydney: reopened at the request of Howard Hinnant.
|
| 895 |
|
|
Post-Redmond: James Kanze noticed that the copy constructors of
|
| 896 |
|
|
exception-derived classes do not have nothrow clauses. Those
|
| 897 |
|
|
classes have no copy constructors declared, meaning the
|
| 898 |
|
|
compiler-generated implicit copy constructors are used, and those
|
| 899 |
|
|
compiler-generated constructors might in principle throw anything.]</i></p>
|
| 900 |
|
|
|
| 901 |
|
|
<hr>
|
| 902 |
|
|
<a name="258"><h3>258. Missing allocator requirement</h3></a><p><b>Section:</b> 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 22 Aug 2000</p>
|
| 903 |
|
|
<p>
|
| 904 |
|
|
>From lib-7752:
|
| 905 |
|
|
</p>
|
| 906 |
|
|
|
| 907 |
|
|
<p>
|
| 908 |
|
|
I've been assuming (and probably everyone else has been assuming) that
|
| 909 |
|
|
allocator instances have a particular property, and I don't think that
|
| 910 |
|
|
property can be deduced from anything in Table 32.
|
| 911 |
|
|
</p>
|
| 912 |
|
|
|
| 913 |
|
|
<p>
|
| 914 |
|
|
I think we have to assume that allocator type conversion is a
|
| 915 |
|
|
homomorphism. That is, if x1 and x2 are of type X, where
|
| 916 |
|
|
X::value_type is T, and if type Y is X::template
|
| 917 |
|
|
rebind<U>::other, then Y(x1) == Y(x2) if and only if x1 == x2.
|
| 918 |
|
|
</p>
|
| 919 |
|
|
|
| 920 |
|
|
<p>
|
| 921 |
|
|
Further discussion: Howard Hinnant writes, in lib-7757:
|
| 922 |
|
|
</p>
|
| 923 |
|
|
|
| 924 |
|
|
<p>
|
| 925 |
|
|
I think I can prove that this is not provable by Table 32. And I agree
|
| 926 |
|
|
it needs to be true except for the "and only if". If x1 != x2, I see no
|
| 927 |
|
|
reason why it can't be true that Y(x1) == Y(x2). Admittedly I can't
|
| 928 |
|
|
think of a practical instance where this would happen, or be valuable.
|
| 929 |
|
|
But I also don't see a need to add that extra restriction. I think we
|
| 930 |
|
|
only need:
|
| 931 |
|
|
</p>
|
| 932 |
|
|
|
| 933 |
|
|
<blockquote>
|
| 934 |
|
|
if (x1 == x2) then Y(x1) == Y(x2)
|
| 935 |
|
|
</blockquote>
|
| 936 |
|
|
|
| 937 |
|
|
<p>
|
| 938 |
|
|
If we decide that == on allocators is transitive, then I think I can
|
| 939 |
|
|
prove the above. But I don't think == is necessarily transitive on
|
| 940 |
|
|
allocators. That is:
|
| 941 |
|
|
</p>
|
| 942 |
|
|
|
| 943 |
|
|
<p>
|
| 944 |
|
|
Given x1 == x2 and x2 == x3, this does not mean x1 == x3.
|
| 945 |
|
|
</p>
|
| 946 |
|
|
|
| 947 |
|
|
<p>Example:</p>
|
| 948 |
|
|
|
| 949 |
|
|
<blockquote>
|
| 950 |
|
|
<p>
|
| 951 |
|
|
x1 can deallocate pointers from: x1, x2, x3 <br>
|
| 952 |
|
|
x2 can deallocate pointers from: x1, x2, x4 <br>
|
| 953 |
|
|
x3 can deallocate pointers from: x1, x3 <br>
|
| 954 |
|
|
x4 can deallocate pointers from: x2, x4
|
| 955 |
|
|
</p>
|
| 956 |
|
|
|
| 957 |
|
|
<p>
|
| 958 |
|
|
x1 == x2, and x2 == x4, but x1 != x4
|
| 959 |
|
|
</p>
|
| 960 |
|
|
</blockquote>
|
| 961 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 962 |
|
|
|
| 963 |
|
|
<p><i>[Toronto: LWG members offered multiple opinions. One
|
| 964 |
|
|
opinion is that it should not be required that <tt>x1 == x2</tt>
|
| 965 |
|
|
implies <tt>Y(x1) == Y(x2)</tt>, and that it should not even be
|
| 966 |
|
|
required that <tt>X(x1) == x1</tt>. Another opinion is that
|
| 967 |
|
|
the second line from the bottom in table 32 already implies the
|
| 968 |
|
|
desired property. This issue should be considered in light of
|
| 969 |
|
|
other issues related to allocator instances.]</i></p>
|
| 970 |
|
|
<hr>
|
| 971 |
|
|
<a name="290"><h3>290. Requirements to for_each and its function object</h3></a><p><b>Section:</b> 25.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.foreach"> [lib.alg.foreach]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> 03 Jan 2001</p>
|
| 972 |
|
|
<p>The specification of the for_each algorithm does not have a
|
| 973 |
|
|
"Requires" section, which means that there are no
|
| 974 |
|
|
restrictions imposed on the function object whatsoever. In essence it
|
| 975 |
|
|
means that I can provide any function object with arbitrary side
|
| 976 |
|
|
effects and I can still expect a predictable result. In particular I
|
| 977 |
|
|
can expect that the function object is applied exactly last - first
|
| 978 |
|
|
times, which is promised in the "Complexity" section.
|
| 979 |
|
|
</p>
|
| 980 |
|
|
|
| 981 |
|
|
<p>I don't see how any implementation can give such a guarantee
|
| 982 |
|
|
without imposing requirements on the function object.
|
| 983 |
|
|
</p>
|
| 984 |
|
|
|
| 985 |
|
|
<p>Just as an example: consider a function object that removes
|
| 986 |
|
|
elements from the input sequence. In that case, what does the
|
| 987 |
|
|
complexity guarantee (applies f exactly last - first times) mean?
|
| 988 |
|
|
</p>
|
| 989 |
|
|
|
| 990 |
|
|
<p>One can argue that this is obviously a nonsensical application and
|
| 991 |
|
|
a theoretical case, which unfortunately it isn't. I have seen
|
| 992 |
|
|
programmers shooting themselves in the foot this way, and they did not
|
| 993 |
|
|
understand that there are restrictions even if the description of the
|
| 994 |
|
|
algorithm does not say so.
|
| 995 |
|
|
</p>
|
| 996 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 997 |
|
|
<p><i>[Lillehammer: This is more general than for_each. We don't want
|
| 998 |
|
|
the function object in transform invalidiating iterators
|
| 999 |
|
|
either. There should be a note somewhere in clause 17 (17, not 25)
|
| 1000 |
|
|
saying that user code operating on a range may not invalidate
|
| 1001 |
|
|
iterators unless otherwise specified. Bill will provide wording.]</i></p>
|
| 1002 |
|
|
|
| 1003 |
|
|
<hr>
|
| 1004 |
|
|
<a name="294"><h3>294. User defined macros and standard headers</h3></a><p><b>Section:</b> 17.4.3.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.macro.names"> [lib.macro.names]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> James Kanze <b>Date:</b> 11 Jan 2001</p>
|
| 1005 |
|
|
<p>Paragraph 2 of 17.4.3.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.macro.names"> [lib.macro.names]</a> reads: "A
|
| 1006 |
|
|
translation unit that includes a header shall not contain any macros
|
| 1007 |
|
|
that define names declared in that header." As I read this, it
|
| 1008 |
|
|
would mean that the following program is legal:</p>
|
| 1009 |
|
|
|
| 1010 |
|
|
<pre> #define npos 3.14
|
| 1011 |
|
|
#include <sstream>
|
| 1012 |
|
|
</pre>
|
| 1013 |
|
|
|
| 1014 |
|
|
<p>since npos is not defined in <sstream>. It is, however, defined
|
| 1015 |
|
|
in <string>, and it is hard to imagine an implementation in
|
| 1016 |
|
|
which <sstream> didn't include <string>.</p>
|
| 1017 |
|
|
|
| 1018 |
|
|
<p>I think that this phrase was probably formulated before it was
|
| 1019 |
|
|
decided that a standard header may freely include other standard
|
| 1020 |
|
|
headers. The phrase would be perfectly appropriate for C, for
|
| 1021 |
|
|
example. In light of 17.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.headers"> [lib.res.on.headers]</a> paragraph 1, however,
|
| 1022 |
|
|
it isn't stringent enough.</p>
|
| 1023 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1024 |
|
|
<p>For 17.4.3.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.macro.names"> [lib.macro.names]</a>, replace the current wording, which reads:</p>
|
| 1025 |
|
|
<blockquote>
|
| 1026 |
|
|
<p>Each name defined as a macro in a header is reserved to the
|
| 1027 |
|
|
implementation for any use if the translation unit includes
|
| 1028 |
|
|
the header.168)</p>
|
| 1029 |
|
|
|
| 1030 |
|
|
<p>A translation unit that includes a header shall not contain any
|
| 1031 |
|
|
macros that define names declared or defined in that header. Nor shall
|
| 1032 |
|
|
such a translation unit define macros for names lexically
|
| 1033 |
|
|
identical to keywords.</p>
|
| 1034 |
|
|
|
| 1035 |
|
|
<p>168) It is not permissible to remove a library macro definition by
|
| 1036 |
|
|
using the #undef directive.</p>
|
| 1037 |
|
|
</blockquote>
|
| 1038 |
|
|
|
| 1039 |
|
|
<p>with the wording:</p>
|
| 1040 |
|
|
|
| 1041 |
|
|
<blockquote>
|
| 1042 |
|
|
<p>A translation unit that includes a standard library header shall not
|
| 1043 |
|
|
#define or #undef names declared in any standard library header.</p>
|
| 1044 |
|
|
|
| 1045 |
|
|
<p>A translation unit shall not #define or #undef names lexically
|
| 1046 |
|
|
identical to keywords.</p>
|
| 1047 |
|
|
</blockquote>
|
| 1048 |
|
|
|
| 1049 |
|
|
<p><i>[Lillehammer: Beman provided new wording]</i></p>
|
| 1050 |
|
|
|
| 1051 |
|
|
<hr>
|
| 1052 |
|
|
<a name="299"><h3>299. Incorrect return types for iterator dereference</h3></a><p><b>Section:</b> 24.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.bidirectional.iterators"> [lib.bidirectional.iterators]</a>, 24.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.random.access.iterators"> [lib.random.access.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> John Potter <b>Date:</b> 22 Jan 2001</p>
|
| 1053 |
|
|
<p>
|
| 1054 |
|
|
In section 24.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.bidirectional.iterators"> [lib.bidirectional.iterators]</a>,
|
| 1055 |
|
|
Table 75 gives the return type of *r-- as convertible to T. This is
|
| 1056 |
|
|
not consistent with Table 74 which gives the return type of *r++ as
|
| 1057 |
|
|
T&. *r++ = t is valid while *r-- = t is invalid.
|
| 1058 |
|
|
</p>
|
| 1059 |
|
|
|
| 1060 |
|
|
<p>
|
| 1061 |
|
|
In section 24.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.random.access.iterators"> [lib.random.access.iterators]</a>,
|
| 1062 |
|
|
Table 76 gives the return type of a[n] as convertible to T. This is
|
| 1063 |
|
|
not consistent with the semantics of *(a + n) which returns T& by
|
| 1064 |
|
|
Table 74. *(a + n) = t is valid while a[n] = t is invalid.
|
| 1065 |
|
|
</p>
|
| 1066 |
|
|
|
| 1067 |
|
|
<p>
|
| 1068 |
|
|
Discussion from the Copenhagen meeting: the first part is
|
| 1069 |
|
|
uncontroversial. The second part, operator[] for Random Access
|
| 1070 |
|
|
Iterators, requires more thought. There are reasonable arguments on
|
| 1071 |
|
|
both sides. Return by value from operator[] enables some potentially
|
| 1072 |
|
|
useful iterators, e.g. a random access "iota iterator" (a.k.a
|
| 1073 |
|
|
"counting iterator" or "int iterator"). There isn't any obvious way
|
| 1074 |
|
|
to do this with return-by-reference, since the reference would be to a
|
| 1075 |
|
|
temporary. On the other hand, <tt>reverse_iterator</tt> takes an
|
| 1076 |
|
|
arbitrary Random Access Iterator as template argument, and its
|
| 1077 |
|
|
operator[] returns by reference. If we decided that the return type
|
| 1078 |
|
|
in Table 76 was correct, we would have to change
|
| 1079 |
|
|
<tt>reverse_iterator</tt>. This change would probably affect user
|
| 1080 |
|
|
code.
|
| 1081 |
|
|
</p>
|
| 1082 |
|
|
|
| 1083 |
|
|
<p>
|
| 1084 |
|
|
History: the contradiction between <tt>reverse_iterator</tt> and the
|
| 1085 |
|
|
Random Access Iterator requirements has been present from an early
|
| 1086 |
|
|
stage. In both the STL proposal adopted by the committee
|
| 1087 |
|
|
(N0527==94-0140) and the STL technical report (HPL-95-11 (R.1), by
|
| 1088 |
|
|
Stepanov and Lee), the Random Access Iterator requirements say that
|
| 1089 |
|
|
operator[]'s return value is "convertible to T". In N0527
|
| 1090 |
|
|
reverse_iterator's operator[] returns by value, but in HPL-95-11
|
| 1091 |
|
|
(R.1), and in the STL implementation that HP released to the public,
|
| 1092 |
|
|
reverse_iterator's operator[] returns by reference. In 1995, the
|
| 1093 |
|
|
standard was amended to reflect the contents of HPL-95-11 (R.1). The
|
| 1094 |
|
|
original intent for operator[] is unclear.
|
| 1095 |
|
|
</p>
|
| 1096 |
|
|
|
| 1097 |
|
|
<p>
|
| 1098 |
|
|
In the long term it may be desirable to add more fine-grained
|
| 1099 |
|
|
iterator requirements, so that access method and traversal strategy
|
| 1100 |
|
|
can be decoupled. (See "Improved Iterator Categories and
|
| 1101 |
|
|
Requirements", N1297 = 01-0011, by Jeremy Siek.) Any decisions
|
| 1102 |
|
|
about issue 299 should keep this possibility in mind.
|
| 1103 |
|
|
</p>
|
| 1104 |
|
|
|
| 1105 |
|
|
<p>Further discussion: I propose a compromise between John Potter's
|
| 1106 |
|
|
resolution, which requires <tt>T&</tt> as the return type of
|
| 1107 |
|
|
<tt>a[n]</tt>, and the current wording, which requires convertible to
|
| 1108 |
|
|
<tt>T</tt>. The compromise is to keep the convertible to <tt>T</tt>
|
| 1109 |
|
|
for the return type of the expression <tt>a[n]</tt>, but to also add
|
| 1110 |
|
|
<tt>a[n] = t</tt> as a valid expression. This compromise "saves" the
|
| 1111 |
|
|
common case uses of random access iterators, while at the same time
|
| 1112 |
|
|
allowing iterators such as counting iterator and caching file
|
| 1113 |
|
|
iterators to remain random access iterators (iterators where the
|
| 1114 |
|
|
lifetime of the object returned by <tt>operator*()</tt> is tied to the
|
| 1115 |
|
|
lifetime of the iterator).
|
| 1116 |
|
|
</p>
|
| 1117 |
|
|
|
| 1118 |
|
|
<p>
|
| 1119 |
|
|
Note that the compromise resolution necessitates a change to
|
| 1120 |
|
|
<tt>reverse_iterator</tt>. It would need to use a proxy to support
|
| 1121 |
|
|
<tt>a[n] = t</tt>.
|
| 1122 |
|
|
</p>
|
| 1123 |
|
|
|
| 1124 |
|
|
<p>
|
| 1125 |
|
|
Note also there is one kind of mutable random access iterator that
|
| 1126 |
|
|
will no longer meet the new requirements. Currently, iterators that
|
| 1127 |
|
|
return an r-value from <tt>operator[]</tt> meet the requirements for a
|
| 1128 |
|
|
mutable random access iterartor, even though the expression <tt>a[n] =
|
| 1129 |
|
|
t</tt> will only modify a temporary that goes away. With this proposed
|
| 1130 |
|
|
resolution, <tt>a[n] = t</tt> will be required to have the same
|
| 1131 |
|
|
operational semantics as <tt>*(a + n) = t</tt>.
|
| 1132 |
|
|
</p>
|
| 1133 |
|
|
|
| 1134 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1135 |
|
|
|
| 1136 |
|
|
<p>
|
| 1137 |
|
|
In section 24.1.4 [lib.bidirectdional.iterators], change the return
|
| 1138 |
|
|
type in table 75 from "convertible to <tt>T</tt>" to
|
| 1139 |
|
|
<tt>T&</tt>.
|
| 1140 |
|
|
</p>
|
| 1141 |
|
|
|
| 1142 |
|
|
<p>
|
| 1143 |
|
|
In section 24.1.5 [lib.random.access.iterators], change the
|
| 1144 |
|
|
operational semantics for <tt>a[n]</tt> to " the r-value of
|
| 1145 |
|
|
<tt>a[n]</tt> is equivalent to the r-value of <tt>*(a +
|
| 1146 |
|
|
n)</tt>". Add a new row in the table for the expression <tt>a[n] = t</tt>
|
| 1147 |
|
|
with a return type of convertible to <tt>T</tt> and operational semantics of
|
| 1148 |
|
|
<tt>*(a + n) = t</tt>.
|
| 1149 |
|
|
</p>
|
| 1150 |
|
|
|
| 1151 |
|
|
<p><i>[Lillehammer: Real problem, but should be addressed as part of
|
| 1152 |
|
|
iterator redesign]</i></p>
|
| 1153 |
|
|
|
| 1154 |
|
|
<hr>
|
| 1155 |
|
|
<a name="342"><h3>342. seek and eofbit</h3></a><p><b>Section:</b> 27.6.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.unformatted"> [lib.istream.unformatted]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 09 Oct 2001</p>
|
| 1156 |
|
|
<p>I think we have a defect.</p>
|
| 1157 |
|
|
|
| 1158 |
|
|
<p>According to lwg issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#60">60</a> which is now a dr, the
|
| 1159 |
|
|
description of seekg in 27.6.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.unformatted"> [lib.istream.unformatted]</a> paragraph 38 now looks
|
| 1160 |
|
|
like:</p>
|
| 1161 |
|
|
|
| 1162 |
|
|
<blockquote>
|
| 1163 |
|
|
Behaves as an unformatted input function (as described in 27.6.1.3,
|
| 1164 |
|
|
paragraph 1), except that it does not count the number of characters
|
| 1165 |
|
|
extracted and does not affect the value returned by subsequent calls to
|
| 1166 |
|
|
gcount(). After constructing a sentry object, if fail() != true,
|
| 1167 |
|
|
executes rdbuf()>pubseekpos( pos).
|
| 1168 |
|
|
</blockquote>
|
| 1169 |
|
|
|
| 1170 |
|
|
<p>And according to lwg issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#243">243</a> which is also now a dr,
|
| 1171 |
|
|
27.6.1.3, paragraph 1 looks like:</p>
|
| 1172 |
|
|
|
| 1173 |
|
|
<blockquote>
|
| 1174 |
|
|
Each unformatted input function begins execution by constructing an
|
| 1175 |
|
|
object of class sentry with the default argument noskipws (second)
|
| 1176 |
|
|
argument true. If the sentry object returns true, when converted to a
|
| 1177 |
|
|
value of type bool, the function endeavors to obtain the requested
|
| 1178 |
|
|
input. Otherwise, if the sentry constructor exits by throwing an
|
| 1179 |
|
|
exception or if the sentry object returns false, when converted to a
|
| 1180 |
|
|
value of type bool, the function returns without attempting to obtain
|
| 1181 |
|
|
any input. In either case the number of extracted characters is set to
|
| 1182 |
|
|
0; unformatted input functions taking a character array of non-zero
|
| 1183 |
|
|
size as an argument shall also store a null character (using charT())
|
| 1184 |
|
|
in the first location of the array. If an exception is thrown during
|
| 1185 |
|
|
input then ios::badbit is turned on in *this'ss error state. If
|
| 1186 |
|
|
(exception()&badbit)!= 0 then the exception is rethrown. It also counts
|
| 1187 |
|
|
the number of characters extracted. If no exception has been thrown it
|
| 1188 |
|
|
ends by storing the count in a member object and returning the value
|
| 1189 |
|
|
specified. In any event the sentry object is destroyed before leaving
|
| 1190 |
|
|
the unformatted input function.
|
| 1191 |
|
|
</blockquote>
|
| 1192 |
|
|
|
| 1193 |
|
|
<p>And finally 27.6.1.1.2/5 says this about sentry:</p>
|
| 1194 |
|
|
|
| 1195 |
|
|
<blockquote>
|
| 1196 |
|
|
If, after any preparation is completed, is.good() is true, ok_ != false
|
| 1197 |
|
|
otherwise, ok_ == false.
|
| 1198 |
|
|
</blockquote>
|
| 1199 |
|
|
|
| 1200 |
|
|
<p>
|
| 1201 |
|
|
So although the seekg paragraph says that the operation proceeds if
|
| 1202 |
|
|
!fail(), the behavior of unformatted functions says the operation
|
| 1203 |
|
|
proceeds only if good(). The two statements are contradictory when only
|
| 1204 |
|
|
eofbit is set. I don't think the current text is clear which condition
|
| 1205 |
|
|
should be respected.
|
| 1206 |
|
|
</p>
|
| 1207 |
|
|
|
| 1208 |
|
|
<p><b>Further discussion from Redmond:</b></p>
|
| 1209 |
|
|
|
| 1210 |
|
|
<p>PJP: It doesn't seem quite right to say that <tt>seekg</tt> is
|
| 1211 |
|
|
"unformatted". That makes specific claims about sentry that
|
| 1212 |
|
|
aren't quite appropriate for seeking, which has less fragile failure
|
| 1213 |
|
|
modes than actual input. If we do really mean that it's unformatted
|
| 1214 |
|
|
input, it should behave the same way as other unformatted input. On
|
| 1215 |
|
|
the other hand, "principle of least surprise" is that seeking from EOF
|
| 1216 |
|
|
ought to be OK.</p>
|
| 1217 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1218 |
|
|
|
| 1219 |
|
|
<p>Change 27.6.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.unformatted"> [lib.istream.unformatted]</a> to:</p>
|
| 1220 |
|
|
<blockquote>
|
| 1221 |
|
|
Behaves as an unformatted input function (as described in 27.6.1.3,
|
| 1222 |
|
|
paragraph 1), except that it does not count the number of characters
|
| 1223 |
|
|
extracted, does not affect the value returned by subsequent calls to
|
| 1224 |
|
|
gcount(), and does not examine the value returned by the sentry
|
| 1225 |
|
|
object. After constructing a sentry object, if <tt>fail() !=
|
| 1226 |
|
|
true</tt>, executes <tt>rdbuf()->pubseekpos(pos)</tt>. In
|
| 1227 |
|
|
case of success, the function calls clear().
|
| 1228 |
|
|
In case of failure, the function calls <tt>setstate(failbit)</tt>
|
| 1229 |
|
|
(which may throw <tt>ios_base::failure</tt>).
|
| 1230 |
|
|
</blockquote>
|
| 1231 |
|
|
|
| 1232 |
|
|
<p><i>[Lillehammer: Matt provided wording.]</i></p>
|
| 1233 |
|
|
|
| 1234 |
|
|
<p><b>Rationale:</b></p>
|
| 1235 |
|
|
<p>In C, fseek does clear EOF. This is probably what most users would
|
| 1236 |
|
|
expect. We agree that having eofbit set should not deter a seek,
|
| 1237 |
|
|
and that a successful seek should clear eofbit. Note
|
| 1238 |
|
|
that <tt>fail()</tt> is true only if <tt>failbit</tt>
|
| 1239 |
|
|
or <tt>badbit</tt> is set, so using <tt>!fail()</tt>, rather
|
| 1240 |
|
|
than <tt>good()</tt>, satisfies this goal.</p>
|
| 1241 |
|
|
<hr>
|
| 1242 |
|
|
<a name="362"><h3>362. bind1st/bind2nd type safety</h3></a><p><b>Section:</b> 20.3.6.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.bind.1st"> [lib.bind.1st]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Andrew Demkin <b>Date:</b> 26 Apr 2002</p>
|
| 1243 |
|
|
<p>
|
| 1244 |
|
|
The definition of bind1st() (20.3.6.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.bind.1st"> [lib.bind.1st]</a>) can result in
|
| 1245 |
|
|
the construction of an unsafe binding between incompatible pointer
|
| 1246 |
|
|
types. For example, given a function whose first parameter type is
|
| 1247 |
|
|
'pointer to T', it's possible without error to bind an argument of
|
| 1248 |
|
|
type 'pointer to U' when U does not derive from T:
|
| 1249 |
|
|
</p>
|
| 1250 |
|
|
<pre> foo(T*, int);
|
| 1251 |
|
|
|
| 1252 |
|
|
struct T {};
|
| 1253 |
|
|
struct U {};
|
| 1254 |
|
|
|
| 1255 |
|
|
U u;
|
| 1256 |
|
|
|
| 1257 |
|
|
int* p;
|
| 1258 |
|
|
int* q;
|
| 1259 |
|
|
|
| 1260 |
|
|
for_each(p, q, bind1st(ptr_fun(foo), &u)); // unsafe binding
|
| 1261 |
|
|
</pre>
|
| 1262 |
|
|
|
| 1263 |
|
|
<p>
|
| 1264 |
|
|
The definition of bind1st() includes a functional-style conversion to
|
| 1265 |
|
|
map its argument to the expected argument type of the bound function
|
| 1266 |
|
|
(see below):
|
| 1267 |
|
|
</p>
|
| 1268 |
|
|
<pre> typename Operation::first_argument_type(x)
|
| 1269 |
|
|
</pre>
|
| 1270 |
|
|
|
| 1271 |
|
|
<p>
|
| 1272 |
|
|
A functional-style conversion (5.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/expr.html#expr.type.conv"> [expr.type.conv]</a>) is defined to be
|
| 1273 |
|
|
semantically equivalent to an explicit cast expression (5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/expr.html#expr.cast"> [expr.cast]</a>), which may (according to 5.4, paragraph 5) be interpreted
|
| 1274 |
|
|
as a reinterpret_cast, thus masking the error.
|
| 1275 |
|
|
</p>
|
| 1276 |
|
|
|
| 1277 |
|
|
<p>The problem and proposed change also apply to 20.3.6.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.bind.2nd"> [lib.bind.2nd]</a>.</p>
|
| 1278 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1279 |
|
|
<p>Add this sentence to the end of 20.3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.binders"> [lib.binders]</a>/1:
|
| 1280 |
|
|
"Binders <tt>bind1st</tt> and <tt>bind2nd</tt> are deprecated in
|
| 1281 |
|
|
favor of <tt>std::tr1::bind</tt>."</p>
|
| 1282 |
|
|
|
| 1283 |
|
|
<p>(Notes to editor: (1) when and if tr1::bind is incorporated into
|
| 1284 |
|
|
the standard, "std::tr1::bind" should be changed to "std::bind". (2)
|
| 1285 |
|
|
20.3.6 should probably be moved to Annex D.</p>
|
| 1286 |
|
|
<p><b>Rationale:</b></p>
|
| 1287 |
|
|
<p>There is no point in fixing bind1st and bind2nd. tr1::bind is a
|
| 1288 |
|
|
superior solution. It solves this problem and others.</p>
|
| 1289 |
|
|
<hr>
|
| 1290 |
|
|
<a name="369"><h3>369. io stream objects and static ctors</h3></a><p><b>Section:</b> 27.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.objects"> [lib.iostream.objects]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Ruslan Abdikeev <b>Date:</b> 8 Jul 2002</p>
|
| 1291 |
|
|
<p>
|
| 1292 |
|
|
Is it safe to use standard iostream objects from constructors of
|
| 1293 |
|
|
static objects? Are standard iostream objects constructed and are
|
| 1294 |
|
|
their associations established at that time?
|
| 1295 |
|
|
</p>
|
| 1296 |
|
|
|
| 1297 |
|
|
<p>Surpisingly enough, Standard does NOT require that.</p>
|
| 1298 |
|
|
|
| 1299 |
|
|
<p>
|
| 1300 |
|
|
27.3/2 [lib.iostream.objects] guarantees that standard iostream
|
| 1301 |
|
|
objects are constructed and their associations are established before
|
| 1302 |
|
|
the body of main() begins execution. It also refers to ios_base::Init
|
| 1303 |
|
|
class as the panacea for constructors of static objects.
|
| 1304 |
|
|
</p>
|
| 1305 |
|
|
|
| 1306 |
|
|
<p>
|
| 1307 |
|
|
However, there's nothing in 27.3 [lib.iostream.objects],
|
| 1308 |
|
|
in 27.4.2 [lib.ios.base], and in 27.4.2.1.6 [lib.ios::Init],
|
| 1309 |
|
|
that would require implementations to allow access to standard
|
| 1310 |
|
|
iostream objects from constructors of static objects.
|
| 1311 |
|
|
</p>
|
| 1312 |
|
|
|
| 1313 |
|
|
<p>Details:</p>
|
| 1314 |
|
|
|
| 1315 |
|
|
<p>Core text refers to some magic object ios_base::Init, which will
|
| 1316 |
|
|
be discussed below:</p>
|
| 1317 |
|
|
|
| 1318 |
|
|
<blockquote>
|
| 1319 |
|
|
"The [standard iostream] objects are constructed, and their
|
| 1320 |
|
|
associations are established at some time prior to or during
|
| 1321 |
|
|
first time an object of class basic_ios<charT,traits>::Init
|
| 1322 |
|
|
is constructed, and in any case before the body of main
|
| 1323 |
|
|
begins execution." (27.3/2 [lib.iostream.objects])
|
| 1324 |
|
|
</blockquote>
|
| 1325 |
|
|
|
| 1326 |
|
|
<p>
|
| 1327 |
|
|
The first <i>non-normative</i> footnote encourages implementations
|
| 1328 |
|
|
to initialize standard iostream objects earlier than required.
|
| 1329 |
|
|
</p>
|
| 1330 |
|
|
|
| 1331 |
|
|
<p>However, the second <i>non-normative</i> footnote makes an explicit
|
| 1332 |
|
|
and unsupported claim:</p>
|
| 1333 |
|
|
|
| 1334 |
|
|
<blockquote>
|
| 1335 |
|
|
"Constructors and destructors for static objects can access these
|
| 1336 |
|
|
[standard iostream] objects to read input from stdin or write output
|
| 1337 |
|
|
to stdout or stderr." (27.3/2 footnote 265 [lib.iostream.objects])
|
| 1338 |
|
|
</blockquote>
|
| 1339 |
|
|
|
| 1340 |
|
|
<p>
|
| 1341 |
|
|
The only bit of magic is related to that ios_base::Init class. AFAIK,
|
| 1342 |
|
|
the rationale behind ios_base::Init was to bring an instance of this
|
| 1343 |
|
|
class to each translation unit which #included <iostream> or
|
| 1344 |
|
|
related header. Such an inclusion would support the claim of footnote
|
| 1345 |
|
|
quoted above, because in order to use some standard iostream object it
|
| 1346 |
|
|
is necessary to #include <iostream>.
|
| 1347 |
|
|
</p>
|
| 1348 |
|
|
|
| 1349 |
|
|
<p>
|
| 1350 |
|
|
However, while Standard explicitly describes ios_base::Init as
|
| 1351 |
|
|
an appropriate class for doing the trick, I failed to found a
|
| 1352 |
|
|
mention of an _instance_ of ios_base::Init in Standard.
|
| 1353 |
|
|
</p>
|
| 1354 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1355 |
|
|
|
| 1356 |
|
|
<p>Add to 27.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.objects"> [lib.iostream.objects]</a>, p2, immediately before the last sentence
|
| 1357 |
|
|
of the paragraph, the following two sentences:</p>
|
| 1358 |
|
|
|
| 1359 |
|
|
<blockquote>
|
| 1360 |
|
|
If a translation unit includes <iostream>, or explicitly
|
| 1361 |
|
|
constructs an ios_base::Init object, these stream objects shall
|
| 1362 |
|
|
be constructed before dynamic initialization of non-local
|
| 1363 |
|
|
objects defined later in that translation unit, and these stream
|
| 1364 |
|
|
objects shall be destroyed after the destruction of dynamically
|
| 1365 |
|
|
initialized non-local objects defined later in that translation unit.
|
| 1366 |
|
|
</blockquote>
|
| 1367 |
|
|
|
| 1368 |
|
|
<p><i>[Lillehammer: Matt provided wording.]</i></p>
|
| 1369 |
|
|
<p><i>[Mont Tremblant: Matt provided revised wording.]</i></p>
|
| 1370 |
|
|
<p><b>Rationale:</b></p>
|
| 1371 |
|
|
<p>
|
| 1372 |
|
|
The original proposed resolution unconditionally required
|
| 1373 |
|
|
implementations to define an ios_base::Init object of some
|
| 1374 |
|
|
implementation-defined name in the header <iostream>. That's an
|
| 1375 |
|
|
overspecification. First, defining the object may be unnecessary
|
| 1376 |
|
|
and even detrimental to performance if an implementation can
|
| 1377 |
|
|
guarantee that the 8 standard iostream objects will be initialized
|
| 1378 |
|
|
before any other user-defined object in a program. Second, there
|
| 1379 |
|
|
is no need to require implementations to document the name of the
|
| 1380 |
|
|
object.</p>
|
| 1381 |
|
|
|
| 1382 |
|
|
<p>
|
| 1383 |
|
|
The new proposed resolution gives users guidance on what they need to
|
| 1384 |
|
|
do to ensure that stream objects are constructed during startup.</p>
|
| 1385 |
|
|
<hr>
|
| 1386 |
|
|
<a name="371"><h3>371. Stability of multiset and multimap member functions</h3></a><p><b>Section:</b> 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Frank Compagner <b>Date:</b> 20 Jul 2002</p>
|
| 1387 |
|
|
<p>
|
| 1388 |
|
|
The requirements for multiset and multimap containers (23.1
|
| 1389 |
|
|
[lib.containers.requirements], 23.1.2 [lib.associative.reqmnts],
|
| 1390 |
|
|
23.3.2 [lib.multimap] and 23.3.4 [lib.multiset]) make no mention of
|
| 1391 |
|
|
the stability of the required (mutating) member functions. It appears
|
| 1392 |
|
|
the standard allows these functions to reorder equivalent elements of
|
| 1393 |
|
|
the container at will, yet the pervasive red-black tree implementation
|
| 1394 |
|
|
appears to provide stable behaviour.
|
| 1395 |
|
|
</p>
|
| 1396 |
|
|
|
| 1397 |
|
|
<p>This is of most concern when considering the behaviour of erase().
|
| 1398 |
|
|
A stability requirement would guarantee the correct working of the
|
| 1399 |
|
|
following 'idiom' that removes elements based on a certain predicate
|
| 1400 |
|
|
function.
|
| 1401 |
|
|
</p>
|
| 1402 |
|
|
|
| 1403 |
|
|
<pre> multimap<int, int> m;
|
| 1404 |
|
|
multimap<int, int>::iterator i = m.begin();
|
| 1405 |
|
|
while (i != m.end()) {
|
| 1406 |
|
|
if (pred(i))
|
| 1407 |
|
|
m.erase (i++);
|
| 1408 |
|
|
else
|
| 1409 |
|
|
++i;
|
| 1410 |
|
|
}
|
| 1411 |
|
|
</pre>
|
| 1412 |
|
|
|
| 1413 |
|
|
<p>
|
| 1414 |
|
|
Although clause 23.1.2/8 guarantees that i remains a valid iterator
|
| 1415 |
|
|
througout this loop, absence of the stability requirement could
|
| 1416 |
|
|
potentially result in elements being skipped. This would make
|
| 1417 |
|
|
this code incorrect, and, furthermore, means that there is no way
|
| 1418 |
|
|
of erasing these elements without iterating first over the entire
|
| 1419 |
|
|
container, and second over the elements to be erased. This would
|
| 1420 |
|
|
be unfortunate, and have a negative impact on both performance and
|
| 1421 |
|
|
code simplicity.
|
| 1422 |
|
|
</p>
|
| 1423 |
|
|
|
| 1424 |
|
|
<p>
|
| 1425 |
|
|
If the stability requirement is intended, it should be made explicit
|
| 1426 |
|
|
(probably through an extra paragraph in clause 23.1.2).
|
| 1427 |
|
|
</p>
|
| 1428 |
|
|
<p>
|
| 1429 |
|
|
If it turns out stability cannot be guaranteed, i'd argue that a
|
| 1430 |
|
|
remark or footnote is called for (also somewhere in clause 23.1.2) to
|
| 1431 |
|
|
warn against relying on stable behaviour (as demonstrated by the code
|
| 1432 |
|
|
above). If most implementations will display stable behaviour, any
|
| 1433 |
|
|
problems emerging on an implementation without stable behaviour will
|
| 1434 |
|
|
be hard to track down by users. This would also make the need for an
|
| 1435 |
|
|
erase_if() member function that much greater.
|
| 1436 |
|
|
</p>
|
| 1437 |
|
|
|
| 1438 |
|
|
<p>This issue is somewhat related to LWG issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">130</a>.</p>
|
| 1439 |
|
|
|
| 1440 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1441 |
|
|
|
| 1442 |
|
|
<p>Add the following to the end of 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> paragraph 4:
|
| 1443 |
|
|
"For <tt>multiset</tt> and <tt>multimap</tt>, <tt>insert</tt>and <tt>erase</tt>
|
| 1444 |
|
|
are <i>stable</i>: they preserve the relative ordering of equivalent
|
| 1445 |
|
|
elements.</p>
|
| 1446 |
|
|
|
| 1447 |
|
|
<p><i>[Lillehammer: Matt provided wording]</i></p>
|
| 1448 |
|
|
<p><i>[Joe Gottman points out that the provided wording does not address
|
| 1449 |
|
|
multimap and multiset. N1780 also addresses this issue and suggests
|
| 1450 |
|
|
wording.]</i></p>
|
| 1451 |
|
|
|
| 1452 |
|
|
<p><i>[Mont Tremblant: Changed set and map to multiset and multimap.]</i></p>
|
| 1453 |
|
|
|
| 1454 |
|
|
<p><b>Rationale:</b></p>
|
| 1455 |
|
|
<p>The LWG agrees that this guarantee is necessary for common user
|
| 1456 |
|
|
idioms to work, and that all existing implementations provide this
|
| 1457 |
|
|
property. Note that this resolution guarantees stability for
|
| 1458 |
|
|
multimap and multiset, not for all associative containers in
|
| 1459 |
|
|
general.</p>
|
| 1460 |
|
|
|
| 1461 |
|
|
<hr>
|
| 1462 |
|
|
<a name="376"><h3>376. basic_streambuf semantics</h3></a><p><b>Section:</b> 27.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf.virtuals"> [lib.stringbuf.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Ray Lischner <b>Date:</b> 14 Aug 2002</p>
|
| 1463 |
|
|
<p>
|
| 1464 |
|
|
In Section 27.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf.virtuals"> [lib.stringbuf.virtuals]</a>, Table 90, the implication is that
|
| 1465 |
|
|
the four conditions should be mutually exclusive, but they are not.
|
| 1466 |
|
|
The first two cases, as written, are subcases of the third.</p>
|
| 1467 |
|
|
|
| 1468 |
|
|
<p>
|
| 1469 |
|
|
As written, it is unclear what should be the result if cases 1 and 2
|
| 1470 |
|
|
are both true, but case 3 is false.
|
| 1471 |
|
|
</p>
|
| 1472 |
|
|
|
| 1473 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1474 |
|
|
|
| 1475 |
|
|
<p>Rewrite these conditions as:</p>
|
| 1476 |
|
|
<blockquote>
|
| 1477 |
|
|
<p>
|
| 1478 |
|
|
(which & (ios_base::in|ios_base::out)) == ios_base::in
|
| 1479 |
|
|
</p>
|
| 1480 |
|
|
|
| 1481 |
|
|
<p>
|
| 1482 |
|
|
(which & (ios_base::in|ios_base::out)) == ios_base::out
|
| 1483 |
|
|
</p>
|
| 1484 |
|
|
|
| 1485 |
|
|
<p>
|
| 1486 |
|
|
(which & (ios_base::in|ios_base::out)) ==
|
| 1487 |
|
|
(ios_base::in|ios_base::out)
|
| 1488 |
|
|
and way == either ios_base::beg or ios_base::end
|
| 1489 |
|
|
</p>
|
| 1490 |
|
|
|
| 1491 |
|
|
<p>Otherwise</p>
|
| 1492 |
|
|
</blockquote>
|
| 1493 |
|
|
|
| 1494 |
|
|
<p><b>Rationale:</b></p>
|
| 1495 |
|
|
<p>It's clear what we wanted to say, we just failed to say it. This
|
| 1496 |
|
|
fixes it.</p>
|
| 1497 |
|
|
<hr>
|
| 1498 |
|
|
<a name="382"><h3>382. codecvt do_in/out result</h3></a><p><b>Section:</b> 22.2.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.codecvt"> [lib.locale.codecvt]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 30 Aug 2002</p>
|
| 1499 |
|
|
<p>
|
| 1500 |
|
|
It seems that the descriptions of codecvt do_in() and do_out() leave
|
| 1501 |
|
|
sufficient room for interpretation so that two implementations of
|
| 1502 |
|
|
codecvt may not work correctly with the same filebuf. Specifically,
|
| 1503 |
|
|
the following seems less than adequately specified:
|
| 1504 |
|
|
</p>
|
| 1505 |
|
|
|
| 1506 |
|
|
<ol>
|
| 1507 |
|
|
<li>
|
| 1508 |
|
|
the conditions under which the functions terminate
|
| 1509 |
|
|
</li>
|
| 1510 |
|
|
<li>
|
| 1511 |
|
|
precisely when the functions return ok
|
| 1512 |
|
|
</li>
|
| 1513 |
|
|
<li>
|
| 1514 |
|
|
precisely when the functions return partial
|
| 1515 |
|
|
</li>
|
| 1516 |
|
|
<li>
|
| 1517 |
|
|
the full set of conditions when the functions return error
|
| 1518 |
|
|
</li>
|
| 1519 |
|
|
</ol>
|
| 1520 |
|
|
|
| 1521 |
|
|
<ol>
|
| 1522 |
|
|
<li>
|
| 1523 |
|
|
22.2.1.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.codecvt.virtuals"> [lib.locale.codecvt.virtuals]</a>, p2 says this about the effects of the
|
| 1524 |
|
|
function: ...Stops if it encounters a character it cannot
|
| 1525 |
|
|
convert... This assumes that there *is* a character to
|
| 1526 |
|
|
convert. What happens when there is a sequence that doesn't form a
|
| 1527 |
|
|
valid source character, such as an unassigned or invalid UNICODE
|
| 1528 |
|
|
character, or a sequence that cannot possibly form a character
|
| 1529 |
|
|
(e.g., the sequence "\xc0\xff" in UTF-8)?
|
| 1530 |
|
|
</li>
|
| 1531 |
|
|
<li>
|
| 1532 |
|
|
Table 53 says that the function returns codecvt_base::ok
|
| 1533 |
|
|
to indicate that the function(s) "completed the conversion."
|
| 1534 |
|
|
Suppose that the source sequence is "\xc0\x80" in UTF-8,
|
| 1535 |
|
|
with from pointing to '\xc0' and (from_end==from + 1).
|
| 1536 |
|
|
It is not clear whether the return value should be ok
|
| 1537 |
|
|
or partial (see below).
|
| 1538 |
|
|
</li>
|
| 1539 |
|
|
<li>
|
| 1540 |
|
|
Table 53 says that the function returns codecvt_base::partial
|
| 1541 |
|
|
if "not all source characters converted." With the from pointers
|
| 1542 |
|
|
set up the same way as above, it is not clear whether the return
|
| 1543 |
|
|
value should be partial or ok (see above).
|
| 1544 |
|
|
</li>
|
| 1545 |
|
|
<li>
|
| 1546 |
|
|
Table 53, in the row describing the meaning of error mistakenly
|
| 1547 |
|
|
refers to a "from_type" character, without the symbol from_type
|
| 1548 |
|
|
having been defined. Most likely, the word "source" character
|
| 1549 |
|
|
is intended, although that is not sufficient. The functions
|
| 1550 |
|
|
may also fail when they encounter an invalid source sequence
|
| 1551 |
|
|
that cannot possibly form a valid source character (e.g., as
|
| 1552 |
|
|
explained in bullet 1 above).
|
| 1553 |
|
|
</li>
|
| 1554 |
|
|
</ol>
|
| 1555 |
|
|
<p>
|
| 1556 |
|
|
Finally, the conditions described at the end of 22.2.1.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.codecvt.virtuals"> [lib.locale.codecvt.virtuals]</a>, p4 don't seem to be possible:
|
| 1557 |
|
|
</p>
|
| 1558 |
|
|
<blockquote>
|
| 1559 |
|
|
"A return value of partial, if (from_next == from_end),
|
| 1560 |
|
|
indicates that either the destination sequence has not
|
| 1561 |
|
|
absorbed all the available destination elements, or that
|
| 1562 |
|
|
additional source elements are needed before another
|
| 1563 |
|
|
destination element can be produced."
|
| 1564 |
|
|
</blockquote>
|
| 1565 |
|
|
<p>
|
| 1566 |
|
|
If the value is partial, it's not clear to me that (from_next
|
| 1567 |
|
|
==from_end) could ever hold if there isn't enough room
|
| 1568 |
|
|
in the destination buffer. In order for (from_next==from_end) to
|
| 1569 |
|
|
hold, all characters in that range must have been successfully
|
| 1570 |
|
|
converted (according to 22.2.1.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.codecvt.virtuals"> [lib.locale.codecvt.virtuals]</a>, p2) and since there are no
|
| 1571 |
|
|
further source characters to convert, no more room in the
|
| 1572 |
|
|
destination buffer can be needed.
|
| 1573 |
|
|
</p>
|
| 1574 |
|
|
<p>
|
| 1575 |
|
|
It's also not clear to me that (from_next==from_end) could ever
|
| 1576 |
|
|
hold if additional source elements are needed to produce another
|
| 1577 |
|
|
destination character (not element as incorrectly stated in the
|
| 1578 |
|
|
text). partial is returned if "not all source characters have
|
| 1579 |
|
|
been converted" according to Table 53, which also implies that
|
| 1580 |
|
|
(from_next==from) does NOT hold.
|
| 1581 |
|
|
</p>
|
| 1582 |
|
|
<p>
|
| 1583 |
|
|
Could it be that the intended qualifying condition was actually
|
| 1584 |
|
|
(from_next != from_end), i.e., that the sentence was supposed
|
| 1585 |
|
|
to read
|
| 1586 |
|
|
</p>
|
| 1587 |
|
|
<blockquote>
|
| 1588 |
|
|
"A return value of partial, if (from_next != from_end),..."
|
| 1589 |
|
|
</blockquote>
|
| 1590 |
|
|
<p>
|
| 1591 |
|
|
which would make perfect sense, since, as far as I understand it,
|
| 1592 |
|
|
partial can only occur if (from_next != from_end)?
|
| 1593 |
|
|
</p>
|
| 1594 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1595 |
|
|
|
| 1596 |
|
|
<p><i>[Lillehammer: Defer for the moment, but this really needs to be
|
| 1597 |
|
|
fixed. Right now, the description of codecvt is too vague for it to
|
| 1598 |
|
|
be a useful contract between providers and clients of codecvt
|
| 1599 |
|
|
facets. (Note that both vendors and users can be both providers and
|
| 1600 |
|
|
clients of codecvt facets.) The major philosophical issue is whether
|
| 1601 |
|
|
the standard should only describe mappings that take a single wide
|
| 1602 |
|
|
character to multiple narrow characters (and vice versa), or whether
|
| 1603 |
|
|
it should describe fully general N-to-M conversions. When the
|
| 1604 |
|
|
original standard was written only the former was contemplated, but
|
| 1605 |
|
|
today, in light of the popularity of utf8 and utf16, that doesn't
|
| 1606 |
|
|
seem sufficient for C++0x. Bill supports general N-to-M conversions;
|
| 1607 |
|
|
we need to make sure Martin and Howard agree.]</i></p>
|
| 1608 |
|
|
|
| 1609 |
|
|
<hr>
|
| 1610 |
|
|
<a name="384"><h3>384. equal_range has unimplementable runtime complexity</h3></a><p><b>Section:</b> 25.3.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.equal.range"> [lib.equal.range]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Hans Bos <b>Date:</b> 18 Oct 2002</p>
|
| 1611 |
|
|
<p>
|
| 1612 |
|
|
Section 25.3.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.equal.range"> [lib.equal.range]</a>
|
| 1613 |
|
|
states that at most 2 * log(last - first) + 1
|
| 1614 |
|
|
comparisons are allowed for equal_range.
|
| 1615 |
|
|
</p>
|
| 1616 |
|
|
|
| 1617 |
|
|
<p>It is not possible to implement equal_range with these constraints.</p>
|
| 1618 |
|
|
|
| 1619 |
|
|
<p>In a range of one element as in:</p>
|
| 1620 |
|
|
<pre> int x = 1;
|
| 1621 |
|
|
equal_range(&x, &x + 1, 1)
|
| 1622 |
|
|
</pre>
|
| 1623 |
|
|
|
| 1624 |
|
|
<p>it is easy to see that at least 2 comparison operations are needed.</p>
|
| 1625 |
|
|
|
| 1626 |
|
|
<p>For this case at most 2 * log(1) + 1 = 1 comparison is allowed.</p>
|
| 1627 |
|
|
|
| 1628 |
|
|
<p>I have checked a few libraries and they all use the same (nonconforming)
|
| 1629 |
|
|
algorithm for equal_range that has a complexity of</p>
|
| 1630 |
|
|
<pre> 2* log(distance(first, last)) + 2.
|
| 1631 |
|
|
</pre>
|
| 1632 |
|
|
<p>I guess this is the algorithm that the standard assumes for equal_range.</p>
|
| 1633 |
|
|
|
| 1634 |
|
|
<p>
|
| 1635 |
|
|
It is easy to see that 2 * log(distance) + 2 comparisons are enough
|
| 1636 |
|
|
since equal range can be implemented with lower_bound and upper_bound
|
| 1637 |
|
|
(both log(distance) + 1).
|
| 1638 |
|
|
</p>
|
| 1639 |
|
|
|
| 1640 |
|
|
<p>
|
| 1641 |
|
|
I think it is better to require something like 2log(distance) + O(1) (or
|
| 1642 |
|
|
even logarithmic as multiset::equal_range).
|
| 1643 |
|
|
Then an implementation has more room to optimize for certain cases (e.g.
|
| 1644 |
|
|
have log(distance) characteristics when at most match is found in the range
|
| 1645 |
|
|
but 2log(distance) + 4 for the worst case).
|
| 1646 |
|
|
</p>
|
| 1647 |
|
|
|
| 1648 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1649 |
|
|
<p>In 25.3.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.lower.bound"> [lib.lower.bound]</a>/4, change <tt>log(last - first) + 1</tt>
|
| 1650 |
|
|
to <tt>log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p>
|
| 1651 |
|
|
|
| 1652 |
|
|
<p>In 25.3.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.upper.bound"> [lib.upper.bound]</a>/4, change <tt>log(last - first) + 1</tt>
|
| 1653 |
|
|
to <tt>log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p>
|
| 1654 |
|
|
|
| 1655 |
|
|
<p>In 25.3.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.equal.range"> [lib.equal.range]</a>/4, change <tt>2*log(last - first) + 1</tt>
|
| 1656 |
|
|
to <tt>2*log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p>
|
| 1657 |
|
|
|
| 1658 |
|
|
<p><i>[Matt provided wording]</i></p>
|
| 1659 |
|
|
<p><b>Rationale:</b></p>
|
| 1660 |
|
|
<p>The LWG considered just saying <i>O</i>(log n) for all three, but
|
| 1661 |
|
|
Ê decided that threw away too much valuable information.Ê The fact
|
| 1662 |
|
|
Ê that lower_bound is twice as fast as equal_range is important.
|
| 1663 |
|
|
Ê However, it's better to allow an arbitrary additive constant than to
|
| 1664 |
|
|
Ê specify an exact count.Ê An exact count would have to
|
| 1665 |
|
|
Ê involve <tt>floor</tt> or <tt>ceil</tt>.Ê It would be too easy to
|
| 1666 |
|
|
Ê get this wrong, and don't provide any substantial value for users.</p>
|
| 1667 |
|
|
<hr>
|
| 1668 |
|
|
<a name="385"><h3>385. Does call by value imply the CopyConstructible requirement?</h3></a><p><b>Section:</b> 17 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.library"> [lib.library]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 23 Oct 2002</p>
|
| 1669 |
|
|
<p>
|
| 1670 |
|
|
Many function templates have parameters that are passed by value;
|
| 1671 |
|
|
a typical example is <tt>find_if</tt>'s <i>pred</i> parameter in
|
| 1672 |
|
|
25.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.find"> [lib.alg.find]</a>. Are the corresponding template parameters
|
| 1673 |
|
|
(<tt>Predicate</tt> in this case) implicitly required to be
|
| 1674 |
|
|
CopyConstructible, or does that need to be spelled out explicitly?
|
| 1675 |
|
|
</p>
|
| 1676 |
|
|
|
| 1677 |
|
|
<p>
|
| 1678 |
|
|
This isn't quite as silly a question as it might seem to be at first
|
| 1679 |
|
|
sight. If you call <tt>find_if</tt> in such a way that template
|
| 1680 |
|
|
argument deduction applies, then of course you'll get call by value
|
| 1681 |
|
|
and you need to provide a copy constructor. If you explicitly provide
|
| 1682 |
|
|
the template arguments, however, you can force call by reference by
|
| 1683 |
|
|
writing something like <tt>find_if<my_iterator,
|
| 1684 |
|
|
my_predicate&></tt>. The question is whether implementation
|
| 1685 |
|
|
are required to accept this, or whether this is ill-formed because
|
| 1686 |
|
|
my_predicate& is not CopyConstructible.
|
| 1687 |
|
|
</p>
|
| 1688 |
|
|
|
| 1689 |
|
|
<p>
|
| 1690 |
|
|
The scope of this problem, if it is a problem, is unknown. Function
|
| 1691 |
|
|
object arguments to generic algorithms in clauses 25 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a>
|
| 1692 |
|
|
and 26 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.numerics"> [lib.numerics]</a> are obvious examples. A review of the whole
|
| 1693 |
|
|
library is necessary.
|
| 1694 |
|
|
</p>
|
| 1695 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1696 |
|
|
<p><i>[
|
| 1697 |
|
|
This is really two issues. First, predicates are typically passed by
|
| 1698 |
|
|
value but we don't say they must be Copy Constructible. They should
|
| 1699 |
|
|
be. Second: is specialization allowed to transform value arguments
|
| 1700 |
|
|
into references? References aren't copy constructible, so this should
|
| 1701 |
|
|
not be allowed.
|
| 1702 |
|
|
]</i></p>
|
| 1703 |
|
|
<hr>
|
| 1704 |
|
|
<a name="387"><h3>387. std::complex over-encapsulated</h3></a><p><b>Section:</b> 26.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.numbers"> [lib.complex.numbers]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Gabriel Dos Reis <b>Date:</b> 8 Nov 2002</p>
|
| 1705 |
|
|
<p>
|
| 1706 |
|
|
The absence of explicit description of std::complex<T> layout
|
| 1707 |
|
|
makes it imposible to reuse existing software developed in traditional
|
| 1708 |
|
|
languages like Fortran or C with unambigous and commonly accepted
|
| 1709 |
|
|
layout assumptions. There ought to be a way for practitioners to
|
| 1710 |
|
|
predict with confidence the layout of std::complex<T> whenever T
|
| 1711 |
|
|
is a numerical datatype. The absence of ways to access individual
|
| 1712 |
|
|
parts of a std::complex<T> object as lvalues unduly promotes
|
| 1713 |
|
|
severe pessimizations. For example, the only way to change,
|
| 1714 |
|
|
independently, the real and imaginary parts is to write something like
|
| 1715 |
|
|
</p>
|
| 1716 |
|
|
|
| 1717 |
|
|
<pre>complex<T> z;
|
| 1718 |
|
|
// ...
|
| 1719 |
|
|
// set the real part to r
|
| 1720 |
|
|
z = complex<T>(r, z.imag());
|
| 1721 |
|
|
// ...
|
| 1722 |
|
|
// set the imaginary part to i
|
| 1723 |
|
|
z = complex<T>(z.real(), i);
|
| 1724 |
|
|
</pre>
|
| 1725 |
|
|
|
| 1726 |
|
|
<p>
|
| 1727 |
|
|
At this point, it seems appropriate to recall that a complex number
|
| 1728 |
|
|
is, in effect, just a pair of numbers with no particular invariant to
|
| 1729 |
|
|
maintain. Existing practice in numerical computations has it that a
|
| 1730 |
|
|
complex number datatype is usually represented by Cartesian
|
| 1731 |
|
|
coordinates. Therefore the over-encapsulation put in the specification
|
| 1732 |
|
|
of std::complex<> is not justified.
|
| 1733 |
|
|
</p>
|
| 1734 |
|
|
|
| 1735 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1736 |
|
|
<p>Add the following requirements to 26.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.numbers"> [lib.complex.numbers]</a> as 26.2/4:</p>
|
| 1737 |
|
|
<blockquote>
|
| 1738 |
|
|
<p>If z is an lvalue expression of type cv std::complex<T> then</p>
|
| 1739 |
|
|
|
| 1740 |
|
|
<ul>
|
| 1741 |
|
|
<li>the expression reinterpret_cast<cv T(&)[2]>(z)
|
| 1742 |
|
|
is well-formed; and</li>
|
| 1743 |
|
|
<li>reinterpret_cast<cvT(&)[2]>(z)[0]designates the
|
| 1744 |
|
|
real part of z; and</li>
|
| 1745 |
|
|
<li>reinterpret_cast<cvT(&)[2]>(z)[1]designates the
|
| 1746 |
|
|
imaginary part of z.</li>
|
| 1747 |
|
|
</ul>
|
| 1748 |
|
|
|
| 1749 |
|
|
<p>
|
| 1750 |
|
|
Moreover, if a is an expression of pointer type cv complex<T>*
|
| 1751 |
|
|
and the expression a[i] is well-defined for an integer expression
|
| 1752 |
|
|
i then:
|
| 1753 |
|
|
</p>
|
| 1754 |
|
|
|
| 1755 |
|
|
<ul>
|
| 1756 |
|
|
<li>reinterpret_cast<cvT*>(a)[2+i] designates the real
|
| 1757 |
|
|
part of a[i]; and</li>
|
| 1758 |
|
|
<li>reinterpret_cast<cv T*>(a)[2+i+1] designates the
|
| 1759 |
|
|
imaginary part of a[i].</li>
|
| 1760 |
|
|
</ul>
|
| 1761 |
|
|
</blockquote>
|
| 1762 |
|
|
|
| 1763 |
|
|
<p>In the header synopsis in 26.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.synopsis"> [lib.complex.synopsis]</a>, replace</p>
|
| 1764 |
|
|
<pre> template<class T> T real(const complex<T>&);
|
| 1765 |
|
|
template<class T> T imag(const complex<T>&);
|
| 1766 |
|
|
</pre>
|
| 1767 |
|
|
|
| 1768 |
|
|
<p>with</p>
|
| 1769 |
|
|
|
| 1770 |
|
|
<pre> template<class T> const T& real(const complex<T>&);
|
| 1771 |
|
|
template<class T> T& real( complex<T>&);
|
| 1772 |
|
|
template<class T> const T& imag(const complex<T>&);
|
| 1773 |
|
|
template<class T> T& imag( complex<T>&);
|
| 1774 |
|
|
</pre>
|
| 1775 |
|
|
|
| 1776 |
|
|
<p>In 26.2.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.value.ops"> [lib.complex.value.ops]</a> paragraph 1, change</p>
|
| 1777 |
|
|
<pre> template<class T> T real(const complex<T>&);
|
| 1778 |
|
|
</pre>
|
| 1779 |
|
|
<p>to</p>
|
| 1780 |
|
|
<pre> template<class T> const T& real(const complex<T>&);
|
| 1781 |
|
|
template<class T> T& real( complex<T>&);
|
| 1782 |
|
|
</pre>
|
| 1783 |
|
|
<p>and change the <b>Returns</b> clause to "<b>Returns:</b> The real
|
| 1784 |
|
|
part of <i>x</i></p>.
|
| 1785 |
|
|
|
| 1786 |
|
|
<p>In 26.2.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.value.ops"> [lib.complex.value.ops]</a> paragraph 2, change</p>
|
| 1787 |
|
|
<pre> template<class T> T imag(const complex<T>&);
|
| 1788 |
|
|
</pre>
|
| 1789 |
|
|
<p>to</p>
|
| 1790 |
|
|
<pre> template<class T> const T& imag(const complex<T>&);
|
| 1791 |
|
|
template<class T> T& imag( complex<T>&);
|
| 1792 |
|
|
</pre>
|
| 1793 |
|
|
<p>and change the <b>Returns</b> clause to "<b>Returns:</b> The imaginary
|
| 1794 |
|
|
part of <i>x</i></p>.
|
| 1795 |
|
|
|
| 1796 |
|
|
<p><i>[Kona: The layout guarantee is absolutely necessary for C
|
| 1797 |
|
|
compatibility. However, there was disagreement about the other part
|
| 1798 |
|
|
of this proposal: retrieving elements of the complex number as
|
| 1799 |
|
|
lvalues. An alternative: continue to have real() and imag() return
|
| 1800 |
|
|
rvalues, but add set_real() and set_imag(). Straw poll: return
|
| 1801 |
|
|
lvalues - 2, add setter functions - 5. Related issue: do we want
|
| 1802 |
|
|
reinterpret_cast as the interface for converting a complex to an
|
| 1803 |
|
|
array of two reals, or do we want to provide a more explicit way of
|
| 1804 |
|
|
doing it? Howard will try to resolve this issue for the next
|
| 1805 |
|
|
meeting.]</i></p>
|
| 1806 |
|
|
|
| 1807 |
|
|
<p><i>[pre-Sydney: Howard summarized the options in n1589.]</i></p>
|
| 1808 |
|
|
|
| 1809 |
|
|
<p><b>Rationale:</b></p>
|
| 1810 |
|
|
<p>The LWG believes that C99 compatibility would be enough
|
| 1811 |
|
|
justification for this change even without other considerations. All
|
| 1812 |
|
|
existing implementations already have the layout proposed here.</p>
|
| 1813 |
|
|
<hr>
|
| 1814 |
|
|
<a name="394"><h3>394. behavior of formatted output on failure</h3></a><p><b>Section:</b> 27.6.2.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.formatted.reqmts"> [lib.ostream.formatted.reqmts]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 27 Dec 2002</p>
|
| 1815 |
|
|
<p>
|
| 1816 |
|
|
There is a contradiction in Formatted output about what bit is
|
| 1817 |
|
|
supposed to be set if the formatting fails. On sentence says it's
|
| 1818 |
|
|
badbit and another that it's failbit.
|
| 1819 |
|
|
</p>
|
| 1820 |
|
|
<p>
|
| 1821 |
|
|
27.6.2.5.1, p1 says in the Common Requirements on Formatted output
|
| 1822 |
|
|
functions:
|
| 1823 |
|
|
</p><pre> ... If the generation fails, then the formatted output function
|
| 1824 |
|
|
does setstate(ios::failbit), which might throw an exception.
|
| 1825 |
|
|
</pre>
|
| 1826 |
|
|
<p></p>
|
| 1827 |
|
|
<p>
|
| 1828 |
|
|
27.6.2.5.2, p1 goes on to say this about Arithmetic Inserters:
|
| 1829 |
|
|
</p>
|
| 1830 |
|
|
<p>
|
| 1831 |
|
|
... The formatting conversion occurs as if it performed the
|
| 1832 |
|
|
following code fragment:
|
| 1833 |
|
|
</p>
|
| 1834 |
|
|
<p>
|
| 1835 |
|
|
</p><pre> bool failed =
|
| 1836 |
|
|
use_facet<num_put<charT,ostreambuf_iterator<charT,traits>
|
| 1837 |
|
|
> >
|
| 1838 |
|
|
(getloc()).put(*this, *this, fill(), val). failed();
|
| 1839 |
|
|
|
| 1840 |
|
|
... If failed is true then does setstate(badbit) ...
|
| 1841 |
|
|
</pre>
|
| 1842 |
|
|
<p></p>
|
| 1843 |
|
|
<p>
|
| 1844 |
|
|
The original intent of the text, according to Jerry Schwarz (see
|
| 1845 |
|
|
c++std-lib-10500), is captured in the following paragraph:
|
| 1846 |
|
|
</p>
|
| 1847 |
|
|
<p>
|
| 1848 |
|
|
In general "badbit" should mean that the stream is unusable because
|
| 1849 |
|
|
of some underlying failure, such as disk full or socket closure;
|
| 1850 |
|
|
"failbit" should mean that the requested formatting wasn't possible
|
| 1851 |
|
|
because of some inconsistency such as negative widths. So typically
|
| 1852 |
|
|
if you clear badbit and try to output something else you'll fail
|
| 1853 |
|
|
again, but if you clear failbit and try to output something else
|
| 1854 |
|
|
you'll succeed.
|
| 1855 |
|
|
</p>
|
| 1856 |
|
|
<p>
|
| 1857 |
|
|
In the case of the arithmetic inserters, since num_put cannot
|
| 1858 |
|
|
report failure by any means other than exceptions (in response
|
| 1859 |
|
|
to which the stream must set badbit, which prevents the kind of
|
| 1860 |
|
|
recoverable error reporting mentioned above), the only other
|
| 1861 |
|
|
detectable failure is if the iterator returned from num_put
|
| 1862 |
|
|
returns true from failed().
|
| 1863 |
|
|
</p>
|
| 1864 |
|
|
<p>
|
| 1865 |
|
|
Since that can only happen (at least with the required iostream
|
| 1866 |
|
|
specializations) under such conditions as the underlying failure
|
| 1867 |
|
|
referred to above (e.g., disk full), setting badbit would seem
|
| 1868 |
|
|
to be the appropriate response (indeed, it is required in
|
| 1869 |
|
|
27.6.2.5.2, p1). It follows that failbit can never be directly
|
| 1870 |
|
|
set by the arithmetic (it can only be set by the sentry object
|
| 1871 |
|
|
under some unspecified conditions).
|
| 1872 |
|
|
</p>
|
| 1873 |
|
|
<p>
|
| 1874 |
|
|
The situation is different for other formatted output functions
|
| 1875 |
|
|
which can fail as a result of the streambuf functions failing
|
| 1876 |
|
|
(they may do so by means other than exceptions), and which are
|
| 1877 |
|
|
then required to set failbit.
|
| 1878 |
|
|
</p>
|
| 1879 |
|
|
<p>
|
| 1880 |
|
|
The contradiction, then, is that ostream::operator<<(int) will
|
| 1881 |
|
|
set badbit if the disk is full, while operator<<(ostream&,
|
| 1882 |
|
|
char) will set failbit under the same conditions. To make the behavior
|
| 1883 |
|
|
consistent, the Common requirements sections for the Formatted output
|
| 1884 |
|
|
functions should be changed as proposed below.
|
| 1885 |
|
|
</p>
|
| 1886 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1887 |
|
|
|
| 1888 |
|
|
|
| 1889 |
|
|
<p><i>[Kona: There's agreement that this is a real issue. What we
|
| 1890 |
|
|
decided at Kona: 1. An error from the buffer (which can be detected
|
| 1891 |
|
|
either directly from streambuf's member functions or by examining a
|
| 1892 |
|
|
streambuf_iterator) should always result in badbit getting set.
|
| 1893 |
|
|
2. There should never be a circumstance where failbit gets set.
|
| 1894 |
|
|
That represents a formatting error, and there are no circumstances
|
| 1895 |
|
|
under which the output facets are specified as signaling a
|
| 1896 |
|
|
formatting error. (Even more so for string output that for numeric
|
| 1897 |
|
|
because there's nothing to format.) If we ever decide to make it
|
| 1898 |
|
|
possible for formatting errors to exist then the facets can signal
|
| 1899 |
|
|
the error directly, and that should go in clause 22, not clause 27.
|
| 1900 |
|
|
3. The phrase "if generation fails" is unclear and should be
|
| 1901 |
|
|
eliminated. It's not clear whether it's intended to mean a buffer
|
| 1902 |
|
|
error (e.g. a full disk), a formatting error, or something else.
|
| 1903 |
|
|
Most people thought it was supposed to refer to buffer errors; if
|
| 1904 |
|
|
so, we should say so. Martin will provide wording.]</i></p>
|
| 1905 |
|
|
|
| 1906 |
|
|
<p><b>Rationale:</b></p>
|
| 1907 |
|
|
|
| 1908 |
|
|
<hr>
|
| 1909 |
|
|
<a name="396"><h3>396. what are characters zero and one</h3></a><p><b>Section:</b> 23.3.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.bitset.cons"> [lib.bitset.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 5 Jan 2003</p>
|
| 1910 |
|
|
<p>
|
| 1911 |
|
|
23.3.5.1, p6 [lib.bitset.cons] talks about a generic character
|
| 1912 |
|
|
having the value of 0 or 1 but there is no definition of what
|
| 1913 |
|
|
that means for charT other than char and wchar_t. And even for
|
| 1914 |
|
|
those two types, the values 0 and 1 are not actually what is
|
| 1915 |
|
|
intended -- the values '0' and '1' are. This, along with the
|
| 1916 |
|
|
converse problem in the description of to_string() in 23.3.5.2,
|
| 1917 |
|
|
p33, looks like a defect remotely related to DR 303.
|
| 1918 |
|
|
</p>
|
| 1919 |
|
|
<p>
|
| 1920 |
|
|
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#303
|
| 1921 |
|
|
</p>
|
| 1922 |
|
|
<pre>23.3.5.1:
|
| 1923 |
|
|
-6- An element of the constructed string has value zero if the
|
| 1924 |
|
|
corresponding character in str, beginning at position pos,
|
| 1925 |
|
|
is 0. Otherwise, the element has the value one.
|
| 1926 |
|
|
</pre>
|
| 1927 |
|
|
<pre>23.3.5.2:
|
| 1928 |
|
|
-33- Effects: Constructs a string object of the appropriate
|
| 1929 |
|
|
type and initializes it to a string of length N characters.
|
| 1930 |
|
|
Each character is determined by the value of its
|
| 1931 |
|
|
corresponding bit position in *this. Character position N
|
| 1932 |
|
|
?- 1 corresponds to bit position zero. Subsequent decreasing
|
| 1933 |
|
|
character positions correspond to increasing bit positions.
|
| 1934 |
|
|
Bit value zero becomes the character 0, bit value one becomes
|
| 1935 |
|
|
the character 1.
|
| 1936 |
|
|
</pre>
|
| 1937 |
|
|
<p>
|
| 1938 |
|
|
Also note the typo in 23.3.5.1, p6: the object under construction
|
| 1939 |
|
|
is a bitset, not a string.
|
| 1940 |
|
|
</p>
|
| 1941 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 1942 |
|
|
<p>Change the constructor's function declaration immediately before
|
| 1943 |
|
|
23.3.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.bitset.cons"> [lib.bitset.cons]</a> p3 to:</p>
|
| 1944 |
|
|
<pre> template <class charT, class traits, class Allocator>
|
| 1945 |
|
|
explicit
|
| 1946 |
|
|
bitset(const basic_string<charT, traits, Allocator>& str,
|
| 1947 |
|
|
typename basic_string<charT, traits, Allocator>::size_type pos = 0,
|
| 1948 |
|
|
typename basic_string<charT, traits, Allocator>::size_type n =
|
| 1949 |
|
|
basic_string<charT, traits, Allocator>::npos,
|
| 1950 |
|
|
charT zero = charT('0'), charT one = charT('1'))
|
| 1951 |
|
|
</pre>
|
| 1952 |
|
|
<p>Change the first two sentences of 23.3.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.bitset.cons"> [lib.bitset.cons]</a> p6 to: "An
|
| 1953 |
|
|
element of the constructed string has value 0 if the corresponding
|
| 1954 |
|
|
character in <i>str</i>, beginning at position <i>pos</i>,
|
| 1955 |
|
|
is <i>zero</i>. Otherwise, the element has the value 1.</p>
|
| 1956 |
|
|
|
| 1957 |
|
|
<p>Change the text of the second sentence in 23.3.5.1, p5 to read:
|
| 1958 |
|
|
"The function then throws invalid_argument if any of the rlen
|
| 1959 |
|
|
characters in str beginning at position pos is other than <i>zero</i>
|
| 1960 |
|
|
or <i>one</i>. The function uses traits::eq() to compare the character
|
| 1961 |
|
|
values."
|
| 1962 |
|
|
</p>
|
| 1963 |
|
|
|
| 1964 |
|
|
<p>Change the declaration of the <tt>to_string</tt> member function
|
| 1965 |
|
|
immediately before 23.3.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.bitset.members"> [lib.bitset.members]</a> p33 to:</p>
|
| 1966 |
|
|
<pre> template <class charT, class traits, class Allocator>
|
| 1967 |
|
|
basic_string<charT, traits, Allocator>
|
| 1968 |
|
|
to_string(charT zero = charT('0'), charT one = charT('1')) const;
|
| 1969 |
|
|
</pre>
|
| 1970 |
|
|
<p>Change the last sentence of 23.3.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.bitset.members"> [lib.bitset.members]</a> p33 to: "Bit
|
| 1971 |
|
|
value 0 becomes the character <tt><i>zero</i></tt>, bit value 1 becomes the
|
| 1972 |
|
|
character <tt><i>one</i></tt>.</p>
|
| 1973 |
|
|
<p>Change 23.3.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.bitset.operators"> [lib.bitset.operators]</a> p8 to:</p>
|
| 1974 |
|
|
<p><b>Returns</b>:</p>
|
| 1975 |
|
|
<pre> os << x.template to_string<charT,traits,allocator<charT> >(
|
| 1976 |
|
|
use_facet<ctype<charT> >(<i>os</i>.getloc()).widen('0'),
|
| 1977 |
|
|
use_facet<ctype<charT> >(<i>os</i>.getloc()).widen('1'));
|
| 1978 |
|
|
</pre>
|
| 1979 |
|
|
<p><b>Rationale:</b></p>
|
| 1980 |
|
|
<p>There is a real problem here: we need the character values of '0'
|
| 1981 |
|
|
and '1', and we have no way to get them since strings don't have
|
| 1982 |
|
|
imbued locales. In principle the "right" solution would be to
|
| 1983 |
|
|
provide an extra object, either a ctype facet or a full locale,
|
| 1984 |
|
|
which would be used to widen '0' and '1'. However, there was some
|
| 1985 |
|
|
discomfort about using such a heavyweight mechanism. The proposed
|
| 1986 |
|
|
resolution allows those users who care about this issue to get it
|
| 1987 |
|
|
right.</p>
|
| 1988 |
|
|
<p>We fix the inserter to use the new arguments. Note that we already
|
| 1989 |
|
|
fixed the analogous problem with the extractor in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#303">303</a>.</p>
|
| 1990 |
|
|
|
| 1991 |
|
|
<hr>
|
| 1992 |
|
|
<a name="397"><h3>397. ostream::sentry dtor throws exceptions</h3></a><p><b>Section:</b> 27.6.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream::sentry"> [lib.ostream::sentry]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 5 Jan 2003</p>
|
| 1993 |
|
|
<p>
|
| 1994 |
|
|
17.4.4.8, p3 prohibits library dtors from throwing exceptions.
|
| 1995 |
|
|
</p>
|
| 1996 |
|
|
<p>
|
| 1997 |
|
|
27.6.2.3, p4 says this about the ostream::sentry dtor:
|
| 1998 |
|
|
</p>
|
| 1999 |
|
|
<pre> -4- If ((os.flags() & ios_base::unitbuf) && !uncaught_exception())
|
| 2000 |
|
|
is true, calls os.flush().
|
| 2001 |
|
|
</pre>
|
| 2002 |
|
|
<p>
|
| 2003 |
|
|
27.6.2.6, p7 that describes ostream::flush() says:
|
| 2004 |
|
|
</p>
|
| 2005 |
|
|
<pre> -7- If rdbuf() is not a null pointer, calls rdbuf()->pubsync().
|
| 2006 |
|
|
If that function returns ?-1 calls setstate(badbit) (which
|
| 2007 |
|
|
may throw ios_base::failure (27.4.4.3)).
|
| 2008 |
|
|
</pre>
|
| 2009 |
|
|
<p>
|
| 2010 |
|
|
That seems like a defect, since both pubsync() and setstate() can
|
| 2011 |
|
|
throw an exception.
|
| 2012 |
|
|
</p>
|
| 2013 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2014 |
|
|
<p><i>[
|
| 2015 |
|
|
The contradiction is real. Clause 17 says destructors may never
|
| 2016 |
|
|
throw exceptions, and clause 27 specifies a destructor that does
|
| 2017 |
|
|
throw. In principle we might change either one. We're leaning
|
| 2018 |
|
|
toward changing clause 17: putting in an "unless otherwise specified"
|
| 2019 |
|
|
clause, and then putting in a footnote saying the sentry destructor
|
| 2020 |
|
|
is the only one that can throw. PJP suggests specifying that
|
| 2021 |
|
|
sentry::~sentry() should internally catch any exceptions it might cause.
|
| 2022 |
|
|
]</i></p>
|
| 2023 |
|
|
<hr>
|
| 2024 |
|
|
<a name="398"><h3>398. effects of end-of-file on unformatted input functions</h3></a><p><b>Section:</b> 27.6.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream::sentry"> [lib.ostream::sentry]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 5 Jan 2003</p>
|
| 2025 |
|
|
<p>
|
| 2026 |
|
|
While reviewing unformatted input member functions of istream
|
| 2027 |
|
|
for their behavior when they encounter end-of-file during input
|
| 2028 |
|
|
I found that the requirements vary, sometimes unexpectedly, and
|
| 2029 |
|
|
in more than one case even contradict established practice (GNU
|
| 2030 |
|
|
libstdc++ 3.2, IBM VAC++ 6.0, STLPort 4.5, SunPro 5.3, HP aCC
|
| 2031 |
|
|
5.38, Rogue Wave libstd 3.1, and Classic Iostreams).
|
| 2032 |
|
|
</p>
|
| 2033 |
|
|
<p>
|
| 2034 |
|
|
The following unformatted input member functions set eofbit if they
|
| 2035 |
|
|
encounter an end-of-file (this is the expected behavior, and also
|
| 2036 |
|
|
the behavior of all major implementations):
|
| 2037 |
|
|
</p>
|
| 2038 |
|
|
<p>
|
| 2039 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2040 |
|
|
get (char_type*, streamsize, char_type);
|
| 2041 |
|
|
</pre>
|
| 2042 |
|
|
<p></p>
|
| 2043 |
|
|
<p>
|
| 2044 |
|
|
Also sets failbit if it fails to extract any characters.
|
| 2045 |
|
|
</p>
|
| 2046 |
|
|
<p>
|
| 2047 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2048 |
|
|
get (char_type*, streamsize);
|
| 2049 |
|
|
</pre>
|
| 2050 |
|
|
<p></p>
|
| 2051 |
|
|
<p>
|
| 2052 |
|
|
Also sets failbit if it fails to extract any characters.
|
| 2053 |
|
|
</p>
|
| 2054 |
|
|
<p>
|
| 2055 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2056 |
|
|
getline (char_type*, streamsize, char_type);
|
| 2057 |
|
|
</pre>
|
| 2058 |
|
|
<p></p>
|
| 2059 |
|
|
<p>
|
| 2060 |
|
|
Also sets failbit if it fails to extract any characters.
|
| 2061 |
|
|
</p>
|
| 2062 |
|
|
<p>
|
| 2063 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2064 |
|
|
getline (char_type*, streamsize);
|
| 2065 |
|
|
</pre>
|
| 2066 |
|
|
<p></p>
|
| 2067 |
|
|
<p>
|
| 2068 |
|
|
Also sets failbit if it fails to extract any characters.
|
| 2069 |
|
|
</p>
|
| 2070 |
|
|
<p>
|
| 2071 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2072 |
|
|
ignore (int, int_type);
|
| 2073 |
|
|
</pre>
|
| 2074 |
|
|
<p></p>
|
| 2075 |
|
|
<p>
|
| 2076 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2077 |
|
|
read (char_type*, streamsize);
|
| 2078 |
|
|
</pre>
|
| 2079 |
|
|
<p></p>
|
| 2080 |
|
|
<p>
|
| 2081 |
|
|
Also sets failbit if it encounters end-of-file.
|
| 2082 |
|
|
</p>
|
| 2083 |
|
|
<p>
|
| 2084 |
|
|
</p><pre> streamsize readsome (char_type*, streamsize);
|
| 2085 |
|
|
</pre>
|
| 2086 |
|
|
<p></p>
|
| 2087 |
|
|
|
| 2088 |
|
|
<p>
|
| 2089 |
|
|
The following unformated input member functions set failbit but
|
| 2090 |
|
|
not eofbit if they encounter an end-of-file (I find this odd
|
| 2091 |
|
|
since the functions make it impossible to distinguish a general
|
| 2092 |
|
|
failure from a failure due to end-of-file; the requirement is
|
| 2093 |
|
|
also in conflict with all major implementation which set both
|
| 2094 |
|
|
eofbit and failbit):
|
| 2095 |
|
|
</p>
|
| 2096 |
|
|
<p>
|
| 2097 |
|
|
</p><pre> int_type get();
|
| 2098 |
|
|
</pre>
|
| 2099 |
|
|
<p></p>
|
| 2100 |
|
|
<p>
|
| 2101 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2102 |
|
|
get (char_type&);
|
| 2103 |
|
|
</pre>
|
| 2104 |
|
|
<p></p>
|
| 2105 |
|
|
<p>
|
| 2106 |
|
|
These functions only set failbit of they extract no characters,
|
| 2107 |
|
|
otherwise they don't set any bits, even on failure (I find this
|
| 2108 |
|
|
inconsistency quite unexpected; the requirement is also in
|
| 2109 |
|
|
conflict with all major implementations which set eofbit
|
| 2110 |
|
|
whenever they encounter end-of-file):
|
| 2111 |
|
|
</p>
|
| 2112 |
|
|
<p>
|
| 2113 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2114 |
|
|
get (basic_streambuf<charT, traits>&, char_type);
|
| 2115 |
|
|
</pre>
|
| 2116 |
|
|
<p></p>
|
| 2117 |
|
|
<p>
|
| 2118 |
|
|
</p><pre> basic_istream<charT, traits>&
|
| 2119 |
|
|
get (basic_streambuf<charT, traits>&);
|
| 2120 |
|
|
</pre>
|
| 2121 |
|
|
<p></p>
|
| 2122 |
|
|
<p>
|
| 2123 |
|
|
This function sets no bits (all implementations except for
|
| 2124 |
|
|
STLport and Classic Iostreams set eofbit when they encounter
|
| 2125 |
|
|
end-of-file):
|
| 2126 |
|
|
</p>
|
| 2127 |
|
|
<p>
|
| 2128 |
|
|
</p><pre> int_type peek ();
|
| 2129 |
|
|
</pre>
|
| 2130 |
|
|
<p></p>
|
| 2131 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2132 |
|
|
<p>Informally, what we want is a global statement of intent saying
|
| 2133 |
|
|
that eofbit gets set if we trip across EOF, and then we can take
|
| 2134 |
|
|
away the specific wording for individual functions. A full review
|
| 2135 |
|
|
is necessary. The wording currently in the standard is a mishmash,
|
| 2136 |
|
|
and changing it on an individual basis wouldn't make things better.
|
| 2137 |
|
|
Dietmar will do this work.</p>
|
| 2138 |
|
|
<hr>
|
| 2139 |
|
|
<a name="401"><h3>401. incorrect type casts in table 32 in lib.allocator.requirements</h3></a><p><b>Section:</b> 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Markus Mauhart <b>Date:</b> 27 Feb 2003</p>
|
| 2140 |
|
|
<p>
|
| 2141 |
|
|
I think that in par2 of 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a> the last two
|
| 2142 |
|
|
lines of table 32 contain two incorrect type casts. The lines are ...
|
| 2143 |
|
|
</p>
|
| 2144 |
|
|
|
| 2145 |
|
|
<pre> a.construct(p,t) Effect: new((void*)p) T(t)
|
| 2146 |
|
|
a.destroy(p) Effect: ((T*)p)?->~T()
|
| 2147 |
|
|
</pre>
|
| 2148 |
|
|
|
| 2149 |
|
|
<p>
|
| 2150 |
|
|
.... with the prerequisits coming from the preceding two paragraphs, especially
|
| 2151 |
|
|
from table 31:
|
| 2152 |
|
|
</p>
|
| 2153 |
|
|
|
| 2154 |
|
|
<pre> alloc<T> a ;// an allocator for T
|
| 2155 |
|
|
alloc<T>::pointer p ;// random access iterator
|
| 2156 |
|
|
// (may be different from T*)
|
| 2157 |
|
|
alloc<T>::reference r = *p;// T&
|
| 2158 |
|
|
T const& t ;
|
| 2159 |
|
|
</pre>
|
| 2160 |
|
|
|
| 2161 |
|
|
<p>
|
| 2162 |
|
|
For that two type casts ("(void*)p" and "(T*)p") to be well-formed
|
| 2163 |
|
|
this would require then conversions to T* and void* for all
|
| 2164 |
|
|
alloc<T>::pointer, so it would implicitely introduce extra
|
| 2165 |
|
|
requirements for alloc<T>::pointer, additionally to the only
|
| 2166 |
|
|
current requirement (being a random access iterator).
|
| 2167 |
|
|
</p>
|
| 2168 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2169 |
|
|
<p>
|
| 2170 |
|
|
"(void*)p" should be replaced with "(void*)&*p" and that
|
| 2171 |
|
|
"((T*)p)?->" should be replaced with "(*p)." or with
|
| 2172 |
|
|
"(&*p)->".
|
| 2173 |
|
|
</p>
|
| 2174 |
|
|
|
| 2175 |
|
|
<p>
|
| 2176 |
|
|
Note: Actually I would prefer to replace "((T*)p)?->dtor_name" with
|
| 2177 |
|
|
"p?->dtor_name", but AFAICS this is not possible cause of an omission
|
| 2178 |
|
|
in 13.5.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/over.html#over.ref"> [over.ref]</a> (for which I have filed another DR on 29.11.2002).
|
| 2179 |
|
|
</p>
|
| 2180 |
|
|
|
| 2181 |
|
|
<p><i>[Kona: The LWG thinks this is somewhere on the border between
|
| 2182 |
|
|
Open and NAD. The intend is clear: <tt>construct</tt> constructs an
|
| 2183 |
|
|
object at the location <i>p</i>. It's reading too much into the
|
| 2184 |
|
|
description to think that literally calling <tt>new</tt> is
|
| 2185 |
|
|
required. Tweaking this description is low priority until we can do
|
| 2186 |
|
|
a thorough review of allocators, and, in particular, allocators with
|
| 2187 |
|
|
non-default pointer types.]</i></p>
|
| 2188 |
|
|
|
| 2189 |
|
|
<hr>
|
| 2190 |
|
|
<a name="408"><h3>408. Is vector<reverse_iterator<char*> > forbidden?</h3></a><p><b>Section:</b> 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 3 June 2003</p>
|
| 2191 |
|
|
<p>
|
| 2192 |
|
|
I've been discussing iterator semantics with Dave Abrahams, and a
|
| 2193 |
|
|
surprise has popped up. I don't think this has been discussed before.
|
| 2194 |
|
|
</p>
|
| 2195 |
|
|
|
| 2196 |
|
|
<p>
|
| 2197 |
|
|
24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a> says that the only operation that can be performed on "singular"
|
| 2198 |
|
|
iterator values is to assign a non-singular value to them. (It
|
| 2199 |
|
|
doesn't say they can be destroyed, and that's probably a defect.)
|
| 2200 |
|
|
Some implementations have taken this to imply that there is no need
|
| 2201 |
|
|
to initialize the data member of a reverse_iterator<> in the default
|
| 2202 |
|
|
constructor. As a result, code like
|
| 2203 |
|
|
</p>
|
| 2204 |
|
|
<blockquote>
|
| 2205 |
|
|
std::vector<std::reverse_iterator<char*> > v(7);
|
| 2206 |
|
|
v.reserve(1000);
|
| 2207 |
|
|
</blockquote>
|
| 2208 |
|
|
<p>
|
| 2209 |
|
|
invokes undefined behavior, because it must default-initialize the
|
| 2210 |
|
|
vector elements, and then copy them to other storage. Of course many
|
| 2211 |
|
|
other vector operations on these adapters are also left undefined,
|
| 2212 |
|
|
and which those are is not reliably deducible from the standard.
|
| 2213 |
|
|
</p>
|
| 2214 |
|
|
|
| 2215 |
|
|
<p>
|
| 2216 |
|
|
I don't think that 24.1 was meant to make standard-library iterator
|
| 2217 |
|
|
types unsafe. Rather, it was meant to restrict what operations may
|
| 2218 |
|
|
be performed by functions which take general user- and standard
|
| 2219 |
|
|
iterators as arguments, so that raw pointers would qualify as
|
| 2220 |
|
|
iterators. However, this is not clear in the text, others have come
|
| 2221 |
|
|
to the opposite conclusion.
|
| 2222 |
|
|
</p>
|
| 2223 |
|
|
|
| 2224 |
|
|
<p>
|
| 2225 |
|
|
One question is whether the standard iterator adaptors have defined
|
| 2226 |
|
|
copy semantics. Another is whether they have defined destructor
|
| 2227 |
|
|
semantics: is
|
| 2228 |
|
|
</p>
|
| 2229 |
|
|
<blockquote>
|
| 2230 |
|
|
{ std::vector<std::reverse_iterator<char*> > v(7); }
|
| 2231 |
|
|
</blockquote>
|
| 2232 |
|
|
<p>
|
| 2233 |
|
|
undefined too?
|
| 2234 |
|
|
</p>
|
| 2235 |
|
|
|
| 2236 |
|
|
<p>
|
| 2237 |
|
|
Note this is not a question of whether algorithms are allowed to
|
| 2238 |
|
|
rely on copy semantics for arbitrary iterators, just whether the
|
| 2239 |
|
|
types we actually supply support those operations. I believe the
|
| 2240 |
|
|
resolution must be expressed in terms of the semantics of the
|
| 2241 |
|
|
adapter's argument type. It should make clear that, e.g., the
|
| 2242 |
|
|
reverse_iterator<T> constructor is actually required to execute
|
| 2243 |
|
|
T(), and so copying is defined if the result of T() is copyable.
|
| 2244 |
|
|
</p>
|
| 2245 |
|
|
|
| 2246 |
|
|
<p>
|
| 2247 |
|
|
Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#235">235</a>, which defines reverse_iterator's default
|
| 2248 |
|
|
constructor more precisely, has some relevance to this issue.
|
| 2249 |
|
|
However, it is not the whole story.
|
| 2250 |
|
|
</p>
|
| 2251 |
|
|
|
| 2252 |
|
|
<p>
|
| 2253 |
|
|
The issue was whether
|
| 2254 |
|
|
</p>
|
| 2255 |
|
|
<blockquote>
|
| 2256 |
|
|
reverse_iterator() { }
|
| 2257 |
|
|
</blockquote>
|
| 2258 |
|
|
<p>
|
| 2259 |
|
|
is allowed, vs.
|
| 2260 |
|
|
</p>
|
| 2261 |
|
|
<blockquote>
|
| 2262 |
|
|
reverse_iterator() : current() { }
|
| 2263 |
|
|
</blockquote>
|
| 2264 |
|
|
|
| 2265 |
|
|
<p>
|
| 2266 |
|
|
The difference is when T is char*, where the first leaves the member
|
| 2267 |
|
|
uninitialized, and possibly equal to an existing pointer value, or
|
| 2268 |
|
|
(on some targets) may result in a hardware trap when copied.
|
| 2269 |
|
|
</p>
|
| 2270 |
|
|
|
| 2271 |
|
|
<p>
|
| 2272 |
|
|
8.5 paragraph 5 seems to make clear that the second is required to
|
| 2273 |
|
|
satisfy DR <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#235">235</a>, at least for non-class Iterator argument
|
| 2274 |
|
|
types.
|
| 2275 |
|
|
</p>
|
| 2276 |
|
|
|
| 2277 |
|
|
<p>
|
| 2278 |
|
|
But that only takes care of reverse_iterator, and doesn't establish
|
| 2279 |
|
|
a policy for all iterators. (The reverse iterator adapter was just
|
| 2280 |
|
|
an example.) In particular, does my function
|
| 2281 |
|
|
</p>
|
| 2282 |
|
|
<blockquote>
|
| 2283 |
|
|
template <typename Iterator>
|
| 2284 |
|
|
void f() { std::vector<Iterator> v(7); }
|
| 2285 |
|
|
</blockquote>
|
| 2286 |
|
|
<p>
|
| 2287 |
|
|
evoke undefined behavior for some conforming iterator definitions?
|
| 2288 |
|
|
I think it does, now, because vector<> will destroy those singular
|
| 2289 |
|
|
iterator values, and that's explicitly disallowed.
|
| 2290 |
|
|
</p>
|
| 2291 |
|
|
|
| 2292 |
|
|
<p>
|
| 2293 |
|
|
24.1 shouldn't give blanket permission to copy all singular iterators,
|
| 2294 |
|
|
because then pointers wouldn't qualify as iterators. However, it
|
| 2295 |
|
|
should allow copying of that subset of singular iterator values that
|
| 2296 |
|
|
are default-initialized, and it should explicitly allow destroying any
|
| 2297 |
|
|
iterator value, singular or not, default-initialized or not.
|
| 2298 |
|
|
</p>
|
| 2299 |
|
|
|
| 2300 |
|
|
<p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#407">407</a></p>
|
| 2301 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2302 |
|
|
|
| 2303 |
|
|
<p><i>[
|
| 2304 |
|
|
We don't want to require all singular iterators to be copyable,
|
| 2305 |
|
|
because that is not the case for pointers. However, default
|
| 2306 |
|
|
construction may be a special case. Issue: is it really default
|
| 2307 |
|
|
construction we want to talk about, or is it something like value
|
| 2308 |
|
|
initialization? We need to check with core to see whether default
|
| 2309 |
|
|
constructed pointers are required to be copyable; if not, it would be
|
| 2310 |
|
|
wrong to impose so strict a requirement for iterators.
|
| 2311 |
|
|
]</i></p>
|
| 2312 |
|
|
|
| 2313 |
|
|
<hr>
|
| 2314 |
|
|
<a name="416"><h3>416. definitions of XXX_MIN and XXX_MAX macros in climits</h3></a><p><b>Section:</b> 18.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.c.limits"> [lib.c.limits]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2315 |
|
|
<p>
|
| 2316 |
|
|
|
| 2317 |
|
|
Given two overloads of the function foo(), one taking an argument of type
|
| 2318 |
|
|
int and the other taking a long, which one will the call foo(LONG_MAX)
|
| 2319 |
|
|
resolve to? The expected answer should be foo(long), but whether that
|
| 2320 |
|
|
is true depends on the #defintion of the LONG_MAX macro, specifically
|
| 2321 |
|
|
its type. This issue is about the fact that the type of these macros
|
| 2322 |
|
|
is not actually required to be the same as the the type each respective
|
| 2323 |
|
|
limit.
|
| 2324 |
|
|
<br>
|
| 2325 |
|
|
|
| 2326 |
|
|
Section 18.2.2 of the C++ Standard does not specify the exact types of
|
| 2327 |
|
|
the XXX_MIN and XXX_MAX macros #defined in the <climits> and <limits.h>
|
| 2328 |
|
|
headers such as INT_MAX and LONG_MAX and instead defers to the C standard.
|
| 2329 |
|
|
<br>
|
| 2330 |
|
|
|
| 2331 |
|
|
Section 5.2.4.2.1, p1 of the C standard specifies that "The values [of
|
| 2332 |
|
|
these constants] shall be replaced by constant expressions suitable for use
|
| 2333 |
|
|
in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX,
|
| 2334 |
|
|
the following shall be replaced by expressions that have the same type as
|
| 2335 |
|
|
would an expression that is an object of the corresponding type converted
|
| 2336 |
|
|
according to the integer promotions."
|
| 2337 |
|
|
<br>
|
| 2338 |
|
|
|
| 2339 |
|
|
The "corresponding type converted according to the integer promotions" for
|
| 2340 |
|
|
LONG_MAX is, according to 6.4.4.1, p5 of the C standard, the type of long
|
| 2341 |
|
|
converted to the first of the following set of types that can represent it:
|
| 2342 |
|
|
int, long int, long long int. So on an implementation where (sizeof(long)
|
| 2343 |
|
|
== sizeof(int)) this type is actually int, while on an implementation where
|
| 2344 |
|
|
(sizeof(long) > sizeof(int)) holds this type will be long.
|
| 2345 |
|
|
<br>
|
| 2346 |
|
|
|
| 2347 |
|
|
This is not an issue in C since the type of the macro cannot be detected
|
| 2348 |
|
|
by any conforming C program, but it presents a portability problem in C++
|
| 2349 |
|
|
where the actual type is easily detectable by overload resolution.
|
| 2350 |
|
|
|
| 2351 |
|
|
</p>
|
| 2352 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2353 |
|
|
|
| 2354 |
|
|
<p><i>[Kona: the LWG does not believe this is a defect. The C macro
|
| 2355 |
|
|
definitions are what they are; we've got a better
|
| 2356 |
|
|
mechanism, <tt>std::numeric_limits</tt>, that is specified more
|
| 2357 |
|
|
precisely than the C limit macros. At most we should add a
|
| 2358 |
|
|
nonnormative note recommending that users who care about the exact
|
| 2359 |
|
|
types of limit quantities should use <limits> instead of
|
| 2360 |
|
|
<climits>.]</i></p>
|
| 2361 |
|
|
|
| 2362 |
|
|
<hr>
|
| 2363 |
|
|
<a name="417"><h3>417. what does ctype::do_widen() return on failure</h3></a><p><b>Section:</b> 22.2.1.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.ctype.virtuals"> [lib.locale.ctype.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2364 |
|
|
<p>
|
| 2365 |
|
|
The Effects and Returns clauses of the do_widen() member function of
|
| 2366 |
|
|
the ctype facet fail to specify the behavior of the function on failure.
|
| 2367 |
|
|
That the function may not be able to simply cast the narrow character
|
| 2368 |
|
|
argument to the type of the result since doing so may yield the wrong value
|
| 2369 |
|
|
for some wchar_t encodings. Popular implementations of ctype<wchar_t> that
|
| 2370 |
|
|
use mbtowc() and UTF-8 as the native encoding (e.g., GNU glibc) will fail
|
| 2371 |
|
|
when the argument's MSB is set. There is no way for the the rest of locale
|
| 2372 |
|
|
and iostream to reliably detect this failure.
|
| 2373 |
|
|
</p>
|
| 2374 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2375 |
|
|
<p><i>[Kona: This is a real problem. Widening can fail. It's unclear
|
| 2376 |
|
|
what the solution should be. Returning WEOF works for the wchar_t
|
| 2377 |
|
|
specialization, but not in general. One option might be to add a
|
| 2378 |
|
|
default, like <i>narrow</i>. But that's an incompatible change.
|
| 2379 |
|
|
Using <i>traits::eof</i> might seem like a good idea, but facets
|
| 2380 |
|
|
don't have access to traits (a recurring problem). We could
|
| 2381 |
|
|
have <i>widen</i> throw an exception, but that's a scary option;
|
| 2382 |
|
|
existing library components aren't written with the assumption
|
| 2383 |
|
|
that <i>widen</i> can throw.]</i></p>
|
| 2384 |
|
|
<hr>
|
| 2385 |
|
|
<a name="418"><h3>418. exceptions thrown during iostream cleanup</h3></a><p><b>Section:</b> 27.4.2.1.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios::Init"> [lib.ios::Init]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2386 |
|
|
<p>
|
| 2387 |
|
|
The dtor of the ios_base::Init object is supposed to call flush() on the
|
| 2388 |
|
|
6 standard iostream objects cout, cerr, clog, wcout, wcerr, and wclog.
|
| 2389 |
|
|
This call may cause an exception to be thrown.
|
| 2390 |
|
|
</p>
|
| 2391 |
|
|
|
| 2392 |
|
|
<p>
|
| 2393 |
|
|
17.4.4.8, p3 prohibits all library destructors from throwing exceptions.
|
| 2394 |
|
|
</p>
|
| 2395 |
|
|
|
| 2396 |
|
|
<p>
|
| 2397 |
|
|
The question is: What should this dtor do if one or more of these calls
|
| 2398 |
|
|
to flush() ends up throwing an exception? This can happen quite easily
|
| 2399 |
|
|
if one of the facets installed in the locale imbued in the iostream
|
| 2400 |
|
|
object throws.
|
| 2401 |
|
|
</p>
|
| 2402 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2403 |
|
|
<p><i>[Kona: We probably can't do much better than what we've got, so
|
| 2404 |
|
|
the LWG is leaning toward NAD. At the point where the standard
|
| 2405 |
|
|
stream objects are being cleaned up, the usual error reporting
|
| 2406 |
|
|
mechanism are all unavailable. And exception from flush at this
|
| 2407 |
|
|
point will definitely cause problems. A quality implementation
|
| 2408 |
|
|
might reasonably swallow the exception, or call abort, or do
|
| 2409 |
|
|
something even more drastic.]</i></p>
|
| 2410 |
|
|
<hr>
|
| 2411 |
|
|
<a name="419"><h3>419. istream extractors not setting failbit if eofbit is already set</h3></a><p><b>Section:</b> 27.6.1.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::sentry"> [lib.istream::sentry]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2412 |
|
|
<p>
|
| 2413 |
|
|
|
| 2414 |
|
|
27.6.1.1.2, p2 says that istream::sentry ctor prepares for input if is.good()
|
| 2415 |
|
|
is true. p4 then goes on to say that the ctor sets the sentry::ok_ member to
|
| 2416 |
|
|
true if the stream state is good after any preparation. 27.6.1.2.1, p1 then
|
| 2417 |
|
|
says that a formatted input function endeavors to obtain the requested input
|
| 2418 |
|
|
if the sentry's operator bool() returns true.
|
| 2419 |
|
|
|
| 2420 |
|
|
Given these requirements, no formatted extractor should ever set failbit if
|
| 2421 |
|
|
the initial stream rdstate() == eofbit. That is contrary to the behavior of
|
| 2422 |
|
|
all implementations I tested. The program below prints out
|
| 2423 |
|
|
|
| 2424 |
|
|
eof = 1, fail = 0
|
| 2425 |
|
|
eof = 1, fail = 1
|
| 2426 |
|
|
|
| 2427 |
|
|
on all of them.
|
| 2428 |
|
|
</p>
|
| 2429 |
|
|
<pre>
|
| 2430 |
|
|
#include <sstream>
|
| 2431 |
|
|
#include <cstdio>
|
| 2432 |
|
|
|
| 2433 |
|
|
int main()
|
| 2434 |
|
|
{
|
| 2435 |
|
|
std::istringstream strm ("1");
|
| 2436 |
|
|
|
| 2437 |
|
|
int i = 0;
|
| 2438 |
|
|
|
| 2439 |
|
|
strm >> i;
|
| 2440 |
|
|
|
| 2441 |
|
|
std::printf ("eof = %d, fail = %d\n",
|
| 2442 |
|
|
!!strm.eof (), !!strm.fail ());
|
| 2443 |
|
|
|
| 2444 |
|
|
strm >> i;
|
| 2445 |
|
|
|
| 2446 |
|
|
std::printf ("eof = %d, fail = %d\n",
|
| 2447 |
|
|
!!strm.eof (), !!strm.fail ());
|
| 2448 |
|
|
}
|
| 2449 |
|
|
|
| 2450 |
|
|
</pre>
|
| 2451 |
|
|
<p>
|
| 2452 |
|
|
<br>
|
| 2453 |
|
|
|
| 2454 |
|
|
Comments from Jerry Schwarz (c++std-lib-11373):
|
| 2455 |
|
|
<br>
|
| 2456 |
|
|
|
| 2457 |
|
|
Jerry Schwarz wrote:
|
| 2458 |
|
|
<br>
|
| 2459 |
|
|
|
| 2460 |
|
|
I don't know where (if anywhere) it says it in the standard, but the
|
| 2461 |
|
|
formatted extractors are supposed to set failbit if they don't extract
|
| 2462 |
|
|
any characters. If they didn't then simple loops like
|
| 2463 |
|
|
<br>
|
| 2464 |
|
|
|
| 2465 |
|
|
while (cin >> x);
|
| 2466 |
|
|
<br>
|
| 2467 |
|
|
|
| 2468 |
|
|
would loop forever.
|
| 2469 |
|
|
<br>
|
| 2470 |
|
|
|
| 2471 |
|
|
Further comments from Martin Sebor:
|
| 2472 |
|
|
<br>
|
| 2473 |
|
|
|
| 2474 |
|
|
The question is which part of the extraction should prevent this from happening
|
| 2475 |
|
|
by setting failbit when eofbit is already set. It could either be the sentry
|
| 2476 |
|
|
object or the extractor. It seems that most implementations have chosen to
|
| 2477 |
|
|
set failbit in the sentry [...] so that's the text that will need to be
|
| 2478 |
|
|
corrected.
|
| 2479 |
|
|
|
| 2480 |
|
|
</p>
|
| 2481 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2482 |
|
|
<p>Kona: Possibly NAD. If eofbit is set then good() will return false. We
|
| 2483 |
|
|
then set <i>ok</i> to false. We believe that the sentry's
|
| 2484 |
|
|
constructor should always set failbit when <i>ok</i> is false, and
|
| 2485 |
|
|
we also think the standard already says that. Possibly it could be
|
| 2486 |
|
|
clearer.</p>
|
| 2487 |
|
|
|
| 2488 |
|
|
<hr>
|
| 2489 |
|
|
<a name="421"><h3>421. is basic_streambuf copy-constructible?</h3></a><p><b>Section:</b> 27.5.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.cons"> [lib.streambuf.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2490 |
|
|
<p>
|
| 2491 |
|
|
The reflector thread starting with c++std-lib-11346 notes that the class
|
| 2492 |
|
|
template basic_streambuf, along with basic_stringbuf and basic_filebuf,
|
| 2493 |
|
|
is copy-constructible but that the semantics of the copy constructors
|
| 2494 |
|
|
are not defined anywhere. Further, different implementations behave
|
| 2495 |
|
|
differently in this respect: some prevent copy construction of objects
|
| 2496 |
|
|
of these types by declaring their copy ctors and assignment operators
|
| 2497 |
|
|
private, others exhibit undefined behavior, while others still give
|
| 2498 |
|
|
these operations well-defined semantics.
|
| 2499 |
|
|
</p>
|
| 2500 |
|
|
|
| 2501 |
|
|
<p>
|
| 2502 |
|
|
Note that this problem doesn't seem to be isolated to just the three
|
| 2503 |
|
|
types mentioned above. A number of other types in the library section
|
| 2504 |
|
|
of the standard provide a compiler-generated copy ctor and assignment
|
| 2505 |
|
|
operator yet fail to specify their semantics. It's believed that the
|
| 2506 |
|
|
only types for which this is actually a problem (i.e. types where the
|
| 2507 |
|
|
compiler-generated default may be inappropriate and may not have been
|
| 2508 |
|
|
intended) are locale facets. See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#439">439</a>.
|
| 2509 |
|
|
</p>
|
| 2510 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2511 |
|
|
<p>
|
| 2512 |
|
|
27.5.2 [lib.streambuf]: Add into the synopsis, public section, just above the destructor declaration:
|
| 2513 |
|
|
</p>
|
| 2514 |
|
|
|
| 2515 |
|
|
<blockquote>
|
| 2516 |
|
|
<pre>basic_streambuf(const basic_streambuf& sb);
|
| 2517 |
|
|
basic_streambuf& operator=(const basic_streambuf& sb);
|
| 2518 |
|
|
</pre>
|
| 2519 |
|
|
</blockquote>
|
| 2520 |
|
|
|
| 2521 |
|
|
<p>Insert after 27.5.2.1, paragraph 2:</p>
|
| 2522 |
|
|
<blockquote>
|
| 2523 |
|
|
<pre>basic_streambuf(const basic_streambuf& sb);
|
| 2524 |
|
|
</pre>
|
| 2525 |
|
|
|
| 2526 |
|
|
<p>Constructs a copy of sb.</p>
|
| 2527 |
|
|
<p>Postcondtions:</p>
|
| 2528 |
|
|
<pre> eback() == sb.eback()
|
| 2529 |
|
|
gptr() == sb.gptr()
|
| 2530 |
|
|
egptr() == sb.egptr()
|
| 2531 |
|
|
pbase() == sb.pbase()
|
| 2532 |
|
|
pptr() == sb.pptr()
|
| 2533 |
|
|
epptr() == sb.epptr()
|
| 2534 |
|
|
getloc() == sb.getloc()
|
| 2535 |
|
|
</pre>
|
| 2536 |
|
|
|
| 2537 |
|
|
<pre>basic_streambuf& operator=(const basic_streambuf& sb);
|
| 2538 |
|
|
</pre>
|
| 2539 |
|
|
|
| 2540 |
|
|
<p>Assigns the data members of sb to this.</p>
|
| 2541 |
|
|
|
| 2542 |
|
|
<p>Postcondtions:</p>
|
| 2543 |
|
|
<pre> eback() == sb.eback()
|
| 2544 |
|
|
gptr() == sb.gptr()
|
| 2545 |
|
|
egptr() == sb.egptr()
|
| 2546 |
|
|
pbase() == sb.pbase()
|
| 2547 |
|
|
pptr() == sb.pptr()
|
| 2548 |
|
|
epptr() == sb.epptr()
|
| 2549 |
|
|
getloc() == sb.getloc()
|
| 2550 |
|
|
</pre>
|
| 2551 |
|
|
|
| 2552 |
|
|
<p>Returns: *this.</p>
|
| 2553 |
|
|
</blockquote>
|
| 2554 |
|
|
|
| 2555 |
|
|
<p>27.7.1 [lib.stringbuf]:</p>
|
| 2556 |
|
|
|
| 2557 |
|
|
<b>Option A:</b>
|
| 2558 |
|
|
|
| 2559 |
|
|
<blockquote>
|
| 2560 |
|
|
<p>Insert into the basic_stringbuf synopsis in the private section:</p>
|
| 2561 |
|
|
|
| 2562 |
|
|
<pre>basic_stringbuf(const basic_stringbuf&); // not defined
|
| 2563 |
|
|
basic_stringbuf& operator=(const basic_stringbuf&); // not defined
|
| 2564 |
|
|
</pre>
|
| 2565 |
|
|
</blockquote>
|
| 2566 |
|
|
|
| 2567 |
|
|
<b>Option B:</b>
|
| 2568 |
|
|
|
| 2569 |
|
|
<blockquote>
|
| 2570 |
|
|
<p>Insert into the basic_stringbuf synopsis in the public section:</p>
|
| 2571 |
|
|
|
| 2572 |
|
|
<pre>basic_stringbuf(const basic_stringbuf& sb);
|
| 2573 |
|
|
basic_stringbuf& operator=(const basic_stringbuf& sb);
|
| 2574 |
|
|
</pre>
|
| 2575 |
|
|
|
| 2576 |
|
|
<p>27.7.1.1, insert after paragraph 4:</p>
|
| 2577 |
|
|
|
| 2578 |
|
|
<pre>basic_stringbuf(const basic_stringbuf& sb);</pre>
|
| 2579 |
|
|
|
| 2580 |
|
|
<p>
|
| 2581 |
|
|
Constructs an independent copy of sb as if with sb.str(), and with the openmode that sb was constructed with.
|
| 2582 |
|
|
</p>
|
| 2583 |
|
|
|
| 2584 |
|
|
<p>Postcondtions: </p>
|
| 2585 |
|
|
<pre> str() == sb.str()
|
| 2586 |
|
|
gptr() - eback() == sb.gptr() - sb.eback()
|
| 2587 |
|
|
egptr() - eback() == sb.egptr() - sb.eback()
|
| 2588 |
|
|
pptr() - pbase() == sb.pptr() - sb.pbase()
|
| 2589 |
|
|
getloc() == sb.getloc()
|
| 2590 |
|
|
</pre>
|
| 2591 |
|
|
|
| 2592 |
|
|
<p>
|
| 2593 |
|
|
Note: The only requirement on epptr() is that it point beyond the
|
| 2594 |
|
|
initialized range if an output sequence exists. There is no requirement
|
| 2595 |
|
|
that epptr() - pbase() == sb.epptr() - sb.pbase().
|
| 2596 |
|
|
</p>
|
| 2597 |
|
|
|
| 2598 |
|
|
<pre>basic_stringbuf& operator=(const basic_stringbuf& sb);</pre>
|
| 2599 |
|
|
<p>After assignment the basic_stringbuf has the same state as if it
|
| 2600 |
|
|
were initially copy constructed from sb, except that the
|
| 2601 |
|
|
basic_stringbuf is allowed to retain any excess capacity it might have,
|
| 2602 |
|
|
which may in turn effect the value of epptr().
|
| 2603 |
|
|
</p>
|
| 2604 |
|
|
</blockquote>
|
| 2605 |
|
|
|
| 2606 |
|
|
<p>27.8.1.1 [lib.filebuf]</p>
|
| 2607 |
|
|
|
| 2608 |
|
|
<p>Insert at the bottom of the basic_filebuf synopsis:</p>
|
| 2609 |
|
|
|
| 2610 |
|
|
<blockquote>
|
| 2611 |
|
|
<pre>private:
|
| 2612 |
|
|
basic_filebuf(const basic_filebuf&); // not defined
|
| 2613 |
|
|
basic_filebuf& operator=(const basic_filebuf&); // not defined
|
| 2614 |
|
|
</pre>
|
| 2615 |
|
|
</blockquote>
|
| 2616 |
|
|
<p><i>[Kona: this is an issue for basic_streambuf itself and for its
|
| 2617 |
|
|
derived classes. We are leaning toward allowing basic_streambuf to
|
| 2618 |
|
|
be copyable, and specifying its precise semantics. (Probably the
|
| 2619 |
|
|
obvious: copying the buffer pointers.) We are less sure whether
|
| 2620 |
|
|
the streambuf derived classes should be copyable. Howard will
|
| 2621 |
|
|
write up a proposal.]</i></p>
|
| 2622 |
|
|
|
| 2623 |
|
|
<p><i>[Sydney: Dietmar presented a new argument against basic_streambuf
|
| 2624 |
|
|
being copyable: it can lead to an encapsulation violation. Filebuf
|
| 2625 |
|
|
inherits from streambuf. Now suppose you inhert a my_hijacking_buf
|
| 2626 |
|
|
from streambuf. You can copy the streambuf portion of a filebuf to a
|
| 2627 |
|
|
my_hijacking_buf, giving you access to the pointers into the
|
| 2628 |
|
|
filebuf's internal buffer. Perhaps not a very strong argument, but
|
| 2629 |
|
|
it was strong enough to make people nervous. There was weak
|
| 2630 |
|
|
preference for having streambuf not be copyable. There was weak
|
| 2631 |
|
|
preference for having stringbuf not be copyable even if streambuf
|
| 2632 |
|
|
is. Move this issue to open for now.
|
| 2633 |
|
|
]</i></p>
|
| 2634 |
|
|
|
| 2635 |
|
|
<p><b>Rationale:</b></p>
|
| 2636 |
|
|
<p>
|
| 2637 |
|
|
27.5.2 [lib.streambuf]: The proposed basic_streambuf copy constructor
|
| 2638 |
|
|
and assignment operator are the same as currently implied by the lack
|
| 2639 |
|
|
of declarations: public and simply copies the data members. This
|
| 2640 |
|
|
resolution is not a change but a clarification of the current
|
| 2641 |
|
|
standard.
|
| 2642 |
|
|
</p>
|
| 2643 |
|
|
|
| 2644 |
|
|
<p>
|
| 2645 |
|
|
27.7.1 [lib.stringbuf]: There are two reasonable options: A) Make
|
| 2646 |
|
|
basic_stringbuf not copyable. This is likely the status-quo of
|
| 2647 |
|
|
current implementations. B) Reasonable copy semantics of
|
| 2648 |
|
|
basic_stringbuf can be defined and implemented. A copyable
|
| 2649 |
|
|
basic_streambuf is arguably more useful than a non-copyable one. This
|
| 2650 |
|
|
should be considered as new functionality and not the fixing of a
|
| 2651 |
|
|
defect. If option B is chosen, ramifications from issue 432 are taken
|
| 2652 |
|
|
into account.
|
| 2653 |
|
|
</p>
|
| 2654 |
|
|
|
| 2655 |
|
|
<p>
|
| 2656 |
|
|
27.8.1.1 [lib.filebuf]: There are no reasonable copy semantics for
|
| 2657 |
|
|
basic_filebuf.
|
| 2658 |
|
|
</p>
|
| 2659 |
|
|
|
| 2660 |
|
|
<hr>
|
| 2661 |
|
|
<a name="422"><h3>422. explicit specializations of member functions of class templates</h3></a><p><b>Section:</b> 17.4.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2662 |
|
|
<p>
|
| 2663 |
|
|
It has been suggested that 17.4.3.1, p1 may or may not allow programs to
|
| 2664 |
|
|
explicitly specialize members of standard templates on user-defined types.
|
| 2665 |
|
|
The answer to the question might have an impact where library requirements
|
| 2666 |
|
|
are given using the "as if" rule. I.e., if programs are allowed to specialize
|
| 2667 |
|
|
member functions they will be able to detect an implementation's strict
|
| 2668 |
|
|
conformance to Effects clauses that describe the behavior of the function
|
| 2669 |
|
|
in terms of the other member function (the one explicitly specialized by
|
| 2670 |
|
|
the program) by relying on the "as if" rule.
|
| 2671 |
|
|
</p>
|
| 2672 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2673 |
|
|
|
| 2674 |
|
|
<p>
|
| 2675 |
|
|
Add the following sentence immediately after the text of 17.4.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a>, p1:
|
| 2676 |
|
|
</p>
|
| 2677 |
|
|
|
| 2678 |
|
|
<blockquote>
|
| 2679 |
|
|
The behavior of a program that declares explicit specializations
|
| 2680 |
|
|
of any members of class templates or explicit specializations of
|
| 2681 |
|
|
any member templates of classes or class templates defined in
|
| 2682 |
|
|
this library is undefined.
|
| 2683 |
|
|
</blockquote>
|
| 2684 |
|
|
|
| 2685 |
|
|
|
| 2686 |
|
|
<p><i>[Kona: straw poll was 6-1 that user programs should not be
|
| 2687 |
|
|
allowed to specialize individual member functions of standard
|
| 2688 |
|
|
library class templates, and that doing so invokes undefined
|
| 2689 |
|
|
behavior. Post-Kona: Martin provided wording.]</i></p>
|
| 2690 |
|
|
|
| 2691 |
|
|
<p><i>[Sydney: The LWG agrees that the standard shouldn't permit users
|
| 2692 |
|
|
to specialize individual member functions unless they specialize the
|
| 2693 |
|
|
whole class, but we're not sure these words say what we want them to;
|
| 2694 |
|
|
they could be read as prohibiting the specialization of any standard
|
| 2695 |
|
|
library class templates. We need to consult with CWG to make sure we
|
| 2696 |
|
|
use the right wording.]</i></p>
|
| 2697 |
|
|
|
| 2698 |
|
|
<hr>
|
| 2699 |
|
|
<a name="423"><h3>423. effects of negative streamsize in iostreams</h3></a><p><b>Section:</b> 27 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2700 |
|
|
|
| 2701 |
|
|
<p>
|
| 2702 |
|
|
A third party test suite tries to exercise istream::ignore(N) with
|
| 2703 |
|
|
a negative value of N and expects that the implementation will treat
|
| 2704 |
|
|
N as if it were 0. Our implementation asserts that (N >= 0) holds and
|
| 2705 |
|
|
aborts the test.
|
| 2706 |
|
|
</p>
|
| 2707 |
|
|
|
| 2708 |
|
|
<p>
|
| 2709 |
|
|
I can't find anything in section 27 that prohibits such values but I don't
|
| 2710 |
|
|
see what the effects of such calls should be, either (this applies to
|
| 2711 |
|
|
a number of unformatted input functions as well as some member functions
|
| 2712 |
|
|
of the basic_streambuf template).
|
| 2713 |
|
|
</p>
|
| 2714 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2715 |
|
|
<p>
|
| 2716 |
|
|
I propose that we add to each function in clause 27 that takes an argument,
|
| 2717 |
|
|
say N, of type streamsize a Requires clause saying that "N >= 0." The intent
|
| 2718 |
|
|
is to allow negative streamsize values in calls to precision() and width()
|
| 2719 |
|
|
but disallow it in calls to streambuf::sgetn(), istream::ignore(), or
|
| 2720 |
|
|
ostream::write().
|
| 2721 |
|
|
</p>
|
| 2722 |
|
|
|
| 2723 |
|
|
<p><i>[Kona: The LWG agreed that this is probably what we want. However, we
|
| 2724 |
|
|
need a review to find all places where functions in clause 27 take
|
| 2725 |
|
|
arguments of type streamsize that shouldn't be allowed to go
|
| 2726 |
|
|
negative. Martin will do that review.]</i></p>
|
| 2727 |
|
|
|
| 2728 |
|
|
<hr>
|
| 2729 |
|
|
<a name="424"><h3>424. normative notes</h3></a><p><b>Section:</b> 17.3.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.structure.summary"> [lib.structure.summary]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2730 |
|
|
|
| 2731 |
|
|
<p>
|
| 2732 |
|
|
The text in 17.3.1.1, p1 says:
|
| 2733 |
|
|
<br>
|
| 2734 |
|
|
|
| 2735 |
|
|
"Paragraphs labelled "Note(s):" or "Example(s):" are informative, other
|
| 2736 |
|
|
paragraphs are normative."
|
| 2737 |
|
|
<br>
|
| 2738 |
|
|
|
| 2739 |
|
|
The library section makes heavy use of paragraphs labeled "Notes(s),"
|
| 2740 |
|
|
some of which are clearly intended to be normative (see list 1), while
|
| 2741 |
|
|
some others are not (see list 2). There are also those where the intent
|
| 2742 |
|
|
is not so clear (see list 3).
|
| 2743 |
|
|
<br>
|
| 2744 |
|
|
|
| 2745 |
|
|
List 1 -- Examples of (presumably) normative Notes:
|
| 2746 |
|
|
<br>
|
| 2747 |
|
|
|
| 2748 |
|
|
20.4.1.1, p3, 20.4.1.1, p10, 21.3.1, p11, 22.1.1.2, p11, 23.2.1.3, p2,
|
| 2749 |
|
|
25.3.7, p3, 26.2.6, p14a, 27.5.2.4.3, p7.
|
| 2750 |
|
|
<br>
|
| 2751 |
|
|
|
| 2752 |
|
|
List 2 -- Examples of (presumably) informative Notes:
|
| 2753 |
|
|
<br>
|
| 2754 |
|
|
|
| 2755 |
|
|
18.4.1.3, p3, 21.3.5.6, p14, 22.2.1.5.2, p3, 25.1.1, p4, 26.2.5, p1,
|
| 2756 |
|
|
27.4.2.5, p6.
|
| 2757 |
|
|
<br>
|
| 2758 |
|
|
|
| 2759 |
|
|
List 3 -- Examples of Notes that are not clearly either normative
|
| 2760 |
|
|
or informative:
|
| 2761 |
|
|
<br>
|
| 2762 |
|
|
|
| 2763 |
|
|
22.1.1.2, p8, 22.1.1.5, p6, 27.5.2.4.5, p4.
|
| 2764 |
|
|
<br>
|
| 2765 |
|
|
|
| 2766 |
|
|
None of these lists is meant to be exhaustive.
|
| 2767 |
|
|
</p>
|
| 2768 |
|
|
|
| 2769 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2770 |
|
|
|
| 2771 |
|
|
<p><i>[Definitely a real problem. The big problem is there's material
|
| 2772 |
|
|
that doesn't quite fit any of the named paragraph categories
|
| 2773 |
|
|
(e.g. <b>Effects</b>). Either we need a new kind of named
|
| 2774 |
|
|
paragraph, or we need to put more material in unnamed paragraphs
|
| 2775 |
|
|
jsut after the signature. We need to talk to the Project Editor
|
| 2776 |
|
|
about how to do this.
|
| 2777 |
|
|
]</i></p>
|
| 2778 |
|
|
|
| 2779 |
|
|
<hr>
|
| 2780 |
|
|
<a name="427"><h3>427. stage 2 and rationale of DR 221</h3></a><p><b>Section:</b> 22.2.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2781 |
|
|
<p>
|
| 2782 |
|
|
The requirements specified in Stage 2 and reiterated in the rationale
|
| 2783 |
|
|
of DR 221 (and echoed again in DR 303) specify that num_get<charT>::
|
| 2784 |
|
|
do_get() compares characters on the stream against the widened elements
|
| 2785 |
|
|
of "012...abc...ABCX+-"
|
| 2786 |
|
|
</p>
|
| 2787 |
|
|
|
| 2788 |
|
|
<p>
|
| 2789 |
|
|
An implementation is required to allow programs to instantiate the num_get
|
| 2790 |
|
|
template on any charT that satisfies the requirements on a user-defined
|
| 2791 |
|
|
character type. These requirements do not include the ability of the
|
| 2792 |
|
|
character type to be equality comparable (the char_traits template must
|
| 2793 |
|
|
be used to perform tests for equality). Hence, the num_get template cannot
|
| 2794 |
|
|
be implemented to support any arbitrary character type. The num_get template
|
| 2795 |
|
|
must either make the assumption that the character type is equality-comparable
|
| 2796 |
|
|
(as some popular implementations do), or it may use char_traits<charT> to do
|
| 2797 |
|
|
the comparisons (some other popular implementations do that). This diversity
|
| 2798 |
|
|
of approaches makes it difficult to write portable programs that attempt to
|
| 2799 |
|
|
instantiate the num_get template on user-defined types.
|
| 2800 |
|
|
</p>
|
| 2801 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2802 |
|
|
<p><i>[Kona: the heart of the problem is that we're theoretically
|
| 2803 |
|
|
supposed to use traits classes for all fundamental character
|
| 2804 |
|
|
operations like assignment and comparison, but facets don't have
|
| 2805 |
|
|
traits parameters. This is a fundamental design flaw and it
|
| 2806 |
|
|
appears all over the place, not just in this one place. It's not
|
| 2807 |
|
|
clear what the correct solution is, but a thorough review of facets
|
| 2808 |
|
|
and traits is in order. The LWG considered and rejected the
|
| 2809 |
|
|
possibility of changing numeric facets to use narrowing instead of
|
| 2810 |
|
|
widening. This may be a good idea for other reasons (see issue
|
| 2811 |
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#459">459</a>), but it doesn't solve the problem raised by this
|
| 2812 |
|
|
issue. Whether we use widen or narrow the <tt>num_get</tt> facet
|
| 2813 |
|
|
still has no idea which traits class the user wants to use for
|
| 2814 |
|
|
the comparison, because only streams, not facets, are passed traits
|
| 2815 |
|
|
classes. The standard does not require that two different
|
| 2816 |
|
|
traits classes with the same <tt>char_type</tt> must necessarily
|
| 2817 |
|
|
have the same behavior.]</i></p>
|
| 2818 |
|
|
|
| 2819 |
|
|
<p>Informally, one possibility: require that some of the basic
|
| 2820 |
|
|
character operations, such as <tt>eq</tt>, <tt>lt</tt>,
|
| 2821 |
|
|
and <tt>assign</tt>, must behave the same way for all traits classes
|
| 2822 |
|
|
with the same <tt>char_type</tt>. If we accept that limitation on
|
| 2823 |
|
|
traits classes, then the facet could reasonably be required to
|
| 2824 |
|
|
use <tt>char_traits<charT></tt></p>.
|
| 2825 |
|
|
|
| 2826 |
|
|
<hr>
|
| 2827 |
|
|
<a name="430"><h3>430. valarray subset operations</h3></a><p><b>Section:</b> 26.3.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.valarray.sub"> [lib.valarray.sub]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p>
|
| 2828 |
|
|
<p>
|
| 2829 |
|
|
The standard fails to specify the behavior of valarray::operator[](slice)
|
| 2830 |
|
|
and other valarray subset operations when they are passed an "invalid"
|
| 2831 |
|
|
slice object, i.e., either a slice that doesn't make sense at all (e.g.,
|
| 2832 |
|
|
slice (0, 1, 0) or one that doesn't specify a valid subset of the valarray
|
| 2833 |
|
|
object (e.g., slice (2, 1, 1) for a valarray of size 1).
|
| 2834 |
|
|
</p>
|
| 2835 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2836 |
|
|
<p><i>[Kona: the LWG believes that invalid slices should invoke
|
| 2837 |
|
|
undefined behavior. Valarrays are supposed to be designed for high
|
| 2838 |
|
|
performance, so we don't want to require specific checking. We
|
| 2839 |
|
|
need wording to express this decision.]</i></p>
|
| 2840 |
|
|
<hr>
|
| 2841 |
|
|
<a name="431"><h3>431. Swapping containers with unequal allocators</h3></a><p><b>Section:</b> 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a>, 25 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 20 Sep 2003</p>
|
| 2842 |
|
|
<p>Clause 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a> paragraph 4 says that implementations
|
| 2843 |
|
|
are permitted to supply containers that are unable to cope with
|
| 2844 |
|
|
allocator instances and that container implementations may assume
|
| 2845 |
|
|
that all instances of an allocator type compare equal. We gave
|
| 2846 |
|
|
implementers this latitude as a temporary hack, and eventually we
|
| 2847 |
|
|
want to get rid of it. What happens when we're dealing with
|
| 2848 |
|
|
allocators that <i>don't</i> compare equal?
|
| 2849 |
|
|
</p>
|
| 2850 |
|
|
|
| 2851 |
|
|
<p>In particular: suppose that <tt>v1</tt> and <tt>v2</tt> are both
|
| 2852 |
|
|
objects of type <tt>vector<int, my_alloc></tt> and that
|
| 2853 |
|
|
<tt>v1.get_allocator() != v2.get_allocator()</tt>. What happens if
|
| 2854 |
|
|
we write <tt>v1.swap(v2)</tt>? Informally, three possibilities:</p>
|
| 2855 |
|
|
|
| 2856 |
|
|
<p>1. This operation is illegal. Perhaps we could say that an
|
| 2857 |
|
|
implementation is required to check and to throw an exception, or
|
| 2858 |
|
|
perhaps we could say it's undefined behavior.</p>
|
| 2859 |
|
|
<p>2. The operation performs a slow swap (i.e. using three
|
| 2860 |
|
|
invocations of <tt>operator=</tt>, leaving each allocator with its
|
| 2861 |
|
|
original container. This would be an O(N) operation.</p>
|
| 2862 |
|
|
<p>3. The operation swaps both the vectors' contents and their
|
| 2863 |
|
|
allocators. This would be an O(1) operation. That is:</p>
|
| 2864 |
|
|
<blockquote>
|
| 2865 |
|
|
<pre> my_alloc a1(...);
|
| 2866 |
|
|
my_alloc a2(...);
|
| 2867 |
|
|
assert(a1 != a2);
|
| 2868 |
|
|
|
| 2869 |
|
|
vector<int, my_alloc> v1(a1);
|
| 2870 |
|
|
vector<int, my_alloc> v2(a2);
|
| 2871 |
|
|
assert(a1 == v1.get_allocator());
|
| 2872 |
|
|
assert(a2 == v2.get_allocator());
|
| 2873 |
|
|
|
| 2874 |
|
|
v1.swap(v2);
|
| 2875 |
|
|
assert(a1 == v2.get_allocator());
|
| 2876 |
|
|
assert(a2 == v1.get_allocator());
|
| 2877 |
|
|
</pre>
|
| 2878 |
|
|
</blockquote>
|
| 2879 |
|
|
|
| 2880 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2881 |
|
|
|
| 2882 |
|
|
<p><i>[Kona: This is part of a general problem. We need a paper
|
| 2883 |
|
|
saying how to deal with unequal allocators in general.]</i></p>
|
| 2884 |
|
|
|
| 2885 |
|
|
<p><i>[pre-Sydney: Howard argues for option 3 in n1599.]</i></p>
|
| 2886 |
|
|
|
| 2887 |
|
|
<hr>
|
| 2888 |
|
|
<a name="446"><h3>446. Iterator equality between different containers</h3></a><p><b>Section:</b> 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>, 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Andy Koenig <b>Date:</b> 16 Dec 2003</p>
|
| 2889 |
|
|
<p>
|
| 2890 |
|
|
What requirements does the standard place on equality comparisons between
|
| 2891 |
|
|
iterators that refer to elements of different containers. For example, if
|
| 2892 |
|
|
v1 and v2 are empty vectors, is v1.end() == v2.end() allowed to yield true?
|
| 2893 |
|
|
Is it allowed to throw an exception?
|
| 2894 |
|
|
</p>
|
| 2895 |
|
|
|
| 2896 |
|
|
<p>
|
| 2897 |
|
|
The standard appears to be silent on both questions.
|
| 2898 |
|
|
</p>
|
| 2899 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2900 |
|
|
|
| 2901 |
|
|
<p><i>[Sydney: The intention is that comparing two iterators from
|
| 2902 |
|
|
different containers is undefined, but it's not clear if we say that,
|
| 2903 |
|
|
or even whether it's something we should be saying in clause 23 or in
|
| 2904 |
|
|
clause 24. Intuitively we might want to say that equality is defined
|
| 2905 |
|
|
only if one iterator is reachable from another, but figuring out how
|
| 2906 |
|
|
to say it in any sensible way is a bit tricky: reachability is defined
|
| 2907 |
|
|
in terms of equality, so we can't also define equality in terms of
|
| 2908 |
|
|
reachability.
|
| 2909 |
|
|
]</i></p>
|
| 2910 |
|
|
|
| 2911 |
|
|
<hr>
|
| 2912 |
|
|
<a name="454"><h3>454. basic_filebuf::open should accept wchar_t names</h3></a><p><b>Section:</b> 27.8.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.members"> [lib.filebuf.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Bill Plauger <b>Date:</b> 30 Jan 2004</p>
|
| 2913 |
|
|
<pre> basic_filebuf *basic_filebuf::open(const char *, ios_base::open_mode);
|
| 2914 |
|
|
</pre>
|
| 2915 |
|
|
|
| 2916 |
|
|
<p>should be supplemented with the overload:</p>
|
| 2917 |
|
|
|
| 2918 |
|
|
<pre> basic_filebuf *basic_filebuf::open(const wchar_t *, ios_base::open_mode);
|
| 2919 |
|
|
</pre>
|
| 2920 |
|
|
|
| 2921 |
|
|
<p>
|
| 2922 |
|
|
Depending on the operating system, one of these forms is fundamental and
|
| 2923 |
|
|
the other requires an implementation-defined mapping to determine the
|
| 2924 |
|
|
actual filename.
|
| 2925 |
|
|
</p>
|
| 2926 |
|
|
|
| 2927 |
|
|
<p><i>[Sydney: Yes, we want to allow wchar_t filenames. Bill will
|
| 2928 |
|
|
provide wording.]</i></p>
|
| 2929 |
|
|
|
| 2930 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 2931 |
|
|
|
| 2932 |
|
|
<p>Change from:</p>
|
| 2933 |
|
|
<blockquote>
|
| 2934 |
|
|
<pre>basic_filebuf<charT,traits>* open(
|
| 2935 |
|
|
const char* s,
|
| 2936 |
|
|
ios_base::openmode mode );
|
| 2937 |
|
|
</pre>
|
| 2938 |
|
|
|
| 2939 |
|
|
<p>
|
| 2940 |
|
|
Effects: If is_open() != false, returns a null pointer.
|
| 2941 |
|
|
Otherwise, initializes the filebuf as required. It then
|
| 2942 |
|
|
opens a file, if possible, whose name is the NTBS s ("as if"
|
| 2943 |
|
|
by calling std::fopen(s,modstr)).</p>
|
| 2944 |
|
|
</blockquote>
|
| 2945 |
|
|
|
| 2946 |
|
|
<p>to:</p>
|
| 2947 |
|
|
|
| 2948 |
|
|
<blockquote>
|
| 2949 |
|
|
<pre>basic_filebuf<charT,traits>* open(
|
| 2950 |
|
|
const char* s,
|
| 2951 |
|
|
ios_base::openmode mode );
|
| 2952 |
|
|
|
| 2953 |
|
|
basic_filebuf<charT,traits>* open(
|
| 2954 |
|
|
const wchar_t* ws,
|
| 2955 |
|
|
ios_base::openmode mode );
|
| 2956 |
|
|
</pre>
|
| 2957 |
|
|
|
| 2958 |
|
|
<p>
|
| 2959 |
|
|
Effects: If is_open() != false, returns a null pointer.
|
| 2960 |
|
|
Otherwise, initializes the filebuf as required. It then
|
| 2961 |
|
|
opens a file, if possible, whose name is the NTBS s ("as if"
|
| 2962 |
|
|
by calling std::fopen(s,modstr)).
|
| 2963 |
|
|
For the second signature, the NTBS s is determined from the
|
| 2964 |
|
|
WCBS ws in an implementation-defined manner.
|
| 2965 |
|
|
</p>
|
| 2966 |
|
|
|
| 2967 |
|
|
<p>
|
| 2968 |
|
|
(NOTE: For a system that "naturally" represents a filename
|
| 2969 |
|
|
as a WCBS, the NTBS s in the first signature may instead
|
| 2970 |
|
|
be mapped to a WCBS; if so, it follows the same mapping
|
| 2971 |
|
|
rules as the first argument to open.)
|
| 2972 |
|
|
</p>
|
| 2973 |
|
|
</blockquote>
|
| 2974 |
|
|
|
| 2975 |
|
|
<p><b>Rationale:</b></p>
|
| 2976 |
|
|
<p>
|
| 2977 |
|
|
Slightly controversial, but by a 7-1 straw poll the LWG agreed to move
|
| 2978 |
|
|
this to Ready. The controversy was because the mapping between wide
|
| 2979 |
|
|
names and files in a filesystem is implementation defined. The
|
| 2980 |
|
|
counterargument, which most but not all LWG members accepted, is that
|
| 2981 |
|
|
the mapping between narrow files names and files is also
|
| 2982 |
|
|
implemenation defined.</p>
|
| 2983 |
|
|
|
| 2984 |
|
|
<p><i>[Lillehammer: Moved back to "open" status, at Beman's urging.
|
| 2985 |
|
|
(1) Why just basic_filebuf, instead of also basic_fstream (and
|
| 2986 |
|
|
possibly other things too). (2) Why not also constructors that take
|
| 2987 |
|
|
std::basic_string? (3) We might want to wait until we see Beman's
|
| 2988 |
|
|
filesystem library; we might decide that it obviates this.]</i></p>
|
| 2989 |
|
|
|
| 2990 |
|
|
<hr>
|
| 2991 |
|
|
<a name="456"><h3>456. Traditional C header files are overspecified</h3></a><p><b>Section:</b> 17.4.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.headers"> [lib.headers]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Bill Plauger <b>Date:</b> 30 Jan 2004</p>
|
| 2992 |
|
|
|
| 2993 |
|
|
<p>The C++ Standard effectively requires that the traditional C headers
|
| 2994 |
|
|
(of the form <xxx.h>) be defined in terms of the newer C++
|
| 2995 |
|
|
headers (of the form <cxxx>). Clauses 17.4.1.2/4 and D.5 combine
|
| 2996 |
|
|
to require that:</p>
|
| 2997 |
|
|
|
| 2998 |
|
|
<ul>
|
| 2999 |
|
|
<li>Including the header <cxxx> declares a C name in namespace std.</li>
|
| 3000 |
|
|
|
| 3001 |
|
|
<li> Including the header <xxx.h> declares a C name in namespace std
|
| 3002 |
|
|
(effectively by including <cxxx>), then imports it into the global
|
| 3003 |
|
|
namespace with an individual using declaration.</li>
|
| 3004 |
|
|
</ul>
|
| 3005 |
|
|
|
| 3006 |
|
|
<p>
|
| 3007 |
|
|
The rules were left in this form despited repeated and heated objections
|
| 3008 |
|
|
from several compiler vendors. The C headers are often beyond the direct
|
| 3009 |
|
|
control of C++ implementors. In some organizations, it's all they can do
|
| 3010 |
|
|
to get a few #ifdef __cplusplus tests added. Third-party library vendors
|
| 3011 |
|
|
can perhaps wrap the C headers. But neither of these approaches supports
|
| 3012 |
|
|
the drastic restructuring required by the C++ Standard. As a result, it is
|
| 3013 |
|
|
still widespread practice to ignore this conformance requirement, nearly
|
| 3014 |
|
|
seven years after the committee last debated this topic. Instead, what is
|
| 3015 |
|
|
often implemented is:
|
| 3016 |
|
|
</p>
|
| 3017 |
|
|
|
| 3018 |
|
|
<ul>
|
| 3019 |
|
|
<li> Including the header <xxx.h> declares a C name in the
|
| 3020 |
|
|
global namespace.</li>
|
| 3021 |
|
|
|
| 3022 |
|
|
<li> Including the header <cxxx> declares a C name in the
|
| 3023 |
|
|
global namespace (effectively by including <xxx.h>), then
|
| 3024 |
|
|
imports it into namespace std with an individual using declaration.</li>
|
| 3025 |
|
|
</ul>
|
| 3026 |
|
|
|
| 3027 |
|
|
<p>
|
| 3028 |
|
|
The practical benefit for implementors with the second approach is that
|
| 3029 |
|
|
they can use existing C library headers, as they are pretty much obliged
|
| 3030 |
|
|
to do. The practical cost for programmers facing a mix of implementations
|
| 3031 |
|
|
is that they have to assume weaker rules:</p>
|
| 3032 |
|
|
|
| 3033 |
|
|
<ul>
|
| 3034 |
|
|
<li> If you want to assuredly declare a C name in the global
|
| 3035 |
|
|
namespace, include <xxx.h>. You may or may not also get the
|
| 3036 |
|
|
declaration in namespace std.</li>
|
| 3037 |
|
|
|
| 3038 |
|
|
<li> If you want to assuredly declare a C name in namespace std,
|
| 3039 |
|
|
include <cxxx.h>. You may or may not also get the declaration in
|
| 3040 |
|
|
the global namespace.</li>
|
| 3041 |
|
|
</ul>
|
| 3042 |
|
|
|
| 3043 |
|
|
<p>
|
| 3044 |
|
|
There also exists the <i>possibility</i> of subtle differences due to
|
| 3045 |
|
|
Koenig lookup, but there are so few non-builtin types defined in the C
|
| 3046 |
|
|
headers that I've yet to see an example of any real problems in this
|
| 3047 |
|
|
area.
|
| 3048 |
|
|
</p>
|
| 3049 |
|
|
|
| 3050 |
|
|
<p>
|
| 3051 |
|
|
It is worth observing that the rate at which programmers fall afoul of
|
| 3052 |
|
|
these differences has remained small, at least as measured by newsgroup
|
| 3053 |
|
|
postings and our own bug reports. (By an overwhelming margin, the
|
| 3054 |
|
|
commonest problem is still that programmers include <string> and can't
|
| 3055 |
|
|
understand why the typename string isn't defined -- this a decade after
|
| 3056 |
|
|
the committee invented namespace std, nominally for the benefit of all
|
| 3057 |
|
|
programmers.)
|
| 3058 |
|
|
</p>
|
| 3059 |
|
|
|
| 3060 |
|
|
<p>
|
| 3061 |
|
|
We should accept the fact that we made a serious mistake and rectify it,
|
| 3062 |
|
|
however belatedly, by explicitly allowing either of the two schemes for
|
| 3063 |
|
|
declaring C names in headers.
|
| 3064 |
|
|
</p>
|
| 3065 |
|
|
|
| 3066 |
|
|
<p><i>[Sydney: This issue has been debated many times, and will
|
| 3067 |
|
|
certainly have to be discussed in full committee before any action
|
| 3068 |
|
|
can be taken. However, the preliminary sentiment of the LWG was in
|
| 3069 |
|
|
favor of the change. (6 yes, 0 no, 2 abstain) Robert Klarer
|
| 3070 |
|
|
suggests that we might also want to undeprecate the
|
| 3071 |
|
|
C-style <tt>.h</tt> headers.]</i></p>
|
| 3072 |
|
|
|
| 3073 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3074 |
|
|
<hr>
|
| 3075 |
|
|
<a name="458"><h3>458. 24.1.5 contains unintented limitation for operator-</h3></a><p><b>Section:</b> 24.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.random.access.iterators"> [lib.random.access.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Daniel Frey <b>Date:</b> 27 Feb 2004</p>
|
| 3076 |
|
|
<p>
|
| 3077 |
|
|
In 24.1.5 [lib.random.access.iterators], table 76 the operational
|
| 3078 |
|
|
semantics for the expression "r -= n" are defined as "return r += -n".
|
| 3079 |
|
|
This means, that the expression -n must be valid, which is not the case
|
| 3080 |
|
|
for unsigned types.
|
| 3081 |
|
|
</p>
|
| 3082 |
|
|
|
| 3083 |
|
|
<p><i>[
|
| 3084 |
|
|
Sydney: Possibly not a real problem, since difference type is required
|
| 3085 |
|
|
to be a signed integer type. However, the wording in the standard may
|
| 3086 |
|
|
be less clear than we would like.
|
| 3087 |
|
|
]</i></p>
|
| 3088 |
|
|
|
| 3089 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3090 |
|
|
<p>
|
| 3091 |
|
|
To remove this limitation, I suggest to change the
|
| 3092 |
|
|
operational semantics for this column to:
|
| 3093 |
|
|
</p>
|
| 3094 |
|
|
<code>
|
| 3095 |
|
|
{ Distance m = n;
|
| 3096 |
|
|
if (m >= 0)
|
| 3097 |
|
|
while (m--) --r;
|
| 3098 |
|
|
else
|
| 3099 |
|
|
while (m++) ++r;
|
| 3100 |
|
|
return r; }
|
| 3101 |
|
|
</code>
|
| 3102 |
|
|
|
| 3103 |
|
|
<hr>
|
| 3104 |
|
|
<a name="459"></a><h3><a name="459">459. Requirement for widening in stage 2 is overspecification</a></h3><p><b>Section:</b> 22.2.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 16 Mar 2004</p>
|
| 3105 |
|
|
<p>When parsing strings of wide-character digits, the standard
|
| 3106 |
|
|
requires the library to widen narrow-character "atoms" and compare
|
| 3107 |
|
|
the widened atoms against the characters that are being parsed.
|
| 3108 |
|
|
Simply narrowing the wide characters would be far simpler, and
|
| 3109 |
|
|
probably more efficient. The two choices are equivalent except in
|
| 3110 |
|
|
convoluted test cases, and many implementations already ignore the
|
| 3111 |
|
|
standard and use narrow instead of widen.</p>
|
| 3112 |
|
|
|
| 3113 |
|
|
<p>
|
| 3114 |
|
|
First, I disagree that using narrow() instead of widen() would
|
| 3115 |
|
|
necessarily have unfortunate performance implications. A possible
|
| 3116 |
|
|
implementation of narrow() that allows num_get to be implemented
|
| 3117 |
|
|
in a much simpler and arguably comparably efficient way as calling
|
| 3118 |
|
|
widen() allows, i.e. without making a virtual call to do_narrow every
|
| 3119 |
|
|
time, is as follows:
|
| 3120 |
|
|
</p>
|
| 3121 |
|
|
|
| 3122 |
|
|
<pre> inline char ctype<wchar_t>::narrow (wchar_t wc, char dflt) const
|
| 3123 |
|
|
{
|
| 3124 |
|
|
const unsigned wi = unsigned (wc);
|
| 3125 |
|
|
|
| 3126 |
|
|
if (wi > UCHAR_MAX)
|
| 3127 |
|
|
return typeid (*this) == typeid (ctype<wchar_t>) ?
|
| 3128 |
|
|
dflt : do_narrow (wc, dflt);
|
| 3129 |
|
|
|
| 3130 |
|
|
if (narrow_ [wi] < 0) {
|
| 3131 |
|
|
const char nc = do_narrow (wc, dflt);
|
| 3132 |
|
|
if (nc == dflt)
|
| 3133 |
|
|
return dflt;
|
| 3134 |
|
|
narrow_ [wi] = nc;
|
| 3135 |
|
|
}
|
| 3136 |
|
|
|
| 3137 |
|
|
return char (narrow_ [wi]);
|
| 3138 |
|
|
}
|
| 3139 |
|
|
</pre>
|
| 3140 |
|
|
|
| 3141 |
|
|
<p>
|
| 3142 |
|
|
Second, I don't think the change proposed in the issue (i.e., to use
|
| 3143 |
|
|
narrow() instead of widen() during Stage 2) would be at all
|
| 3144 |
|
|
drastic. Existing implementations with the exception of libstdc++
|
| 3145 |
|
|
currently already use narrow() so the impact of the change on programs
|
| 3146 |
|
|
would presumably be isolated to just a single implementation. Further,
|
| 3147 |
|
|
since narrow() is not required to translate alternate wide digit
|
| 3148 |
|
|
representations such as those mentioned in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#303">303</a> to
|
| 3149 |
|
|
their narrow equivalents (i.e., the portable source characters '0'
|
| 3150 |
|
|
through '9'), the change does not necessarily imply that these
|
| 3151 |
|
|
alternate digits would be treated as ordinary digits and accepted as
|
| 3152 |
|
|
part of numbers during parsing. In fact, the requirement in 22.2.1.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.ctype.virtuals"> [lib.locale.ctype.virtuals]</a>, p13 forbids narrow() to translate an alternate
|
| 3153 |
|
|
digit character, wc, to an ordinary digit in the basic source
|
| 3154 |
|
|
character set unless the expression
|
| 3155 |
|
|
(ctype<charT>::is(ctype_base::digit, wc) == true) holds. This in
|
| 3156 |
|
|
turn is prohibited by the C standard (7.25.2.1.5, 7.25.2.1.5, and
|
| 3157 |
|
|
5.2.1, respectively) for charT of either char or wchar_t.
|
| 3158 |
|
|
</p>
|
| 3159 |
|
|
|
| 3160 |
|
|
<p><i>[Sydney: To a large extent this is a nonproblem. As long as
|
| 3161 |
|
|
you're only trafficking in char and wchar_t we're only dealing with a
|
| 3162 |
|
|
stable character set, so you don't really need either 'widen' or
|
| 3163 |
|
|
'narrow': can just use literals. Finally, it's not even clear whether
|
| 3164 |
|
|
widen-vs-narrow is the right question; arguably we should be using
|
| 3165 |
|
|
codecvt instead.]</i></p>
|
| 3166 |
|
|
|
| 3167 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3168 |
|
|
<p>Change stage 2 so that implementations are permitted to use either
|
| 3169 |
|
|
technique to perform the comparison:</p>
|
| 3170 |
|
|
<ol>
|
| 3171 |
|
|
<li> call widen on the atoms and compare (either by using
|
| 3172 |
|
|
operator== or char_traits<charT>::eq) the input with
|
| 3173 |
|
|
the widened atoms, or</li>
|
| 3174 |
|
|
<li> call narrow on the input and compare the narrow input
|
| 3175 |
|
|
with the atoms</li>
|
| 3176 |
|
|
<li> do (1) or (2) only if charT is not char or wchar_t,
|
| 3177 |
|
|
respectively; i.e., avoid calling widen or narrow
|
| 3178 |
|
|
if it the source and destination types are the same</li>
|
| 3179 |
|
|
</ol>
|
| 3180 |
|
|
<hr>
|
| 3181 |
|
|
<a name="462"><h3>462. Destroying objects with static storage duration</h3></a><p><b>Section:</b> 3.6.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/basic.html#basic.start.term"> [basic.start.term]</a>, 18.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.support.start.term"> [lib.support.start.term]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Bill Plauger <b>Date:</b> 23 Mar 2004</p>
|
| 3182 |
|
|
<p>
|
| 3183 |
|
|
3.6.3 Termination spells out in detail the interleaving of static
|
| 3184 |
|
|
destructor calls and calls to functions registered with atexit. To
|
| 3185 |
|
|
match this behavior requires intimate cooperation between the code
|
| 3186 |
|
|
that calls destructors and the exit/atexit machinery. The former
|
| 3187 |
|
|
is tied tightly to the compiler; the latter is a primitive mechanism
|
| 3188 |
|
|
inherited from C that traditionally has nothing to do with static
|
| 3189 |
|
|
construction and destruction. The benefits of intermixing destructor
|
| 3190 |
|
|
calls with atexit handler calls is questionable at best, and <i>very</i>
|
| 3191 |
|
|
difficult to get right, particularly when mixing third-party C++
|
| 3192 |
|
|
libraries with different third-party C++ compilers and C libraries
|
| 3193 |
|
|
supplied by still other parties.
|
| 3194 |
|
|
</p>
|
| 3195 |
|
|
|
| 3196 |
|
|
<p>
|
| 3197 |
|
|
I believe the right thing to do is defer all static destruction
|
| 3198 |
|
|
until after all atexit handlers are called. This is a change in
|
| 3199 |
|
|
behavior, but one that is likely visible only to perverse test
|
| 3200 |
|
|
suites. At the very least, we should <i>permit</i> deferred destruction
|
| 3201 |
|
|
even if we don't require it.
|
| 3202 |
|
|
</p>
|
| 3203 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3204 |
|
|
|
| 3205 |
|
|
<p><i>[If this is to be changed, it should probably be changed by CWG.
|
| 3206 |
|
|
At this point, however, the LWG is leaning toward NAD. Implementing
|
| 3207 |
|
|
what the standard says is hard work, but it's not impossible and
|
| 3208 |
|
|
most vendors went through that pain years ago. Changing this
|
| 3209 |
|
|
behavior would be a user-visible change, and would break at least
|
| 3210 |
|
|
one real application.]</i></p>
|
| 3211 |
|
|
|
| 3212 |
|
|
<p>
|
| 3213 |
|
|
</p>
|
| 3214 |
|
|
<hr>
|
| 3215 |
|
|
<a name="463"><h3>463. auto_ptr usability issues</h3></a><p><b>Section:</b> 20.4.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.auto.ptr"> [lib.auto.ptr]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Rani Sharoni <b>Date:</b> 7 Dec 2003</p>
|
| 3216 |
|
|
|
| 3217 |
|
|
<p>
|
| 3218 |
|
|
TC1 CWG DR #84 effectively made the template<class Y> operator auto_ptr<Y>()
|
| 3219 |
|
|
member of auto_ptr (20.4.5.3/4) obsolete.
|
| 3220 |
|
|
</p>
|
| 3221 |
|
|
|
| 3222 |
|
|
<p>
|
| 3223 |
|
|
The sole purpose of this obsolete conversion member is to enable copy
|
| 3224 |
|
|
initialization base from r-value derived (or any convertible types like
|
| 3225 |
|
|
cv-types) case:
|
| 3226 |
|
|
</p>
|
| 3227 |
|
|
<pre>#include <memory>
|
| 3228 |
|
|
using std::auto_ptr;
|
| 3229 |
|
|
|
| 3230 |
|
|
struct B {};
|
| 3231 |
|
|
struct D : B {};
|
| 3232 |
|
|
|
| 3233 |
|
|
auto_ptr<D> source();
|
| 3234 |
|
|
int sink(auto_ptr<B>);
|
| 3235 |
|
|
int x1 = sink( source() ); // #1 EDG - no suitable copy constructor
|
| 3236 |
|
|
</pre>
|
| 3237 |
|
|
|
| 3238 |
|
|
<p>
|
| 3239 |
|
|
The excellent analysis of conversion operations that was given in the final
|
| 3240 |
|
|
auto_ptr proposal
|
| 3241 |
|
|
(http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/1997/N1128.pdf)
|
| 3242 |
|
|
explicitly specifies this case analysis (case 4). DR #84 makes the analysis
|
| 3243 |
|
|
wrong and actually comes to forbid the loophole that was exploited by the
|
| 3244 |
|
|
auto_ptr designers.
|
| 3245 |
|
|
</p>
|
| 3246 |
|
|
|
| 3247 |
|
|
<p>
|
| 3248 |
|
|
I didn't encounter any compliant compiler (e.g. EDG, GCC, BCC and VC) that
|
| 3249 |
|
|
ever allowed this case. This is probably because it requires 3 user defined
|
| 3250 |
|
|
conversions and in fact current compilers conform to DR #84.
|
| 3251 |
|
|
</p>
|
| 3252 |
|
|
|
| 3253 |
|
|
<p>
|
| 3254 |
|
|
I was surprised to discover that the obsolete conversion member actually has
|
| 3255 |
|
|
negative impact of the copy initialization base from l-value derived
|
| 3256 |
|
|
case:</p>
|
| 3257 |
|
|
<pre>auto_ptr<D> dp;
|
| 3258 |
|
|
int x2 = sink(dp); // #2 EDG - more than one user-defined conversion applies
|
| 3259 |
|
|
</pre>
|
| 3260 |
|
|
|
| 3261 |
|
|
<p>
|
| 3262 |
|
|
I'm sure that the original intention was allowing this initialization using
|
| 3263 |
|
|
the template<class Y> auto_ptr(auto_ptr<Y>& a) constructor (20.4.5.1/4) but
|
| 3264 |
|
|
since in this copy initialization it's merely user defined conversion (UDC)
|
| 3265 |
|
|
and the obsolete conversion member is UDC with the same rank (for the early
|
| 3266 |
|
|
overloading stage) there is an ambiguity between them.
|
| 3267 |
|
|
</p>
|
| 3268 |
|
|
|
| 3269 |
|
|
<p>
|
| 3270 |
|
|
Removing the obsolete member will have impact on code that explicitly
|
| 3271 |
|
|
invokes it:
|
| 3272 |
|
|
</p>
|
| 3273 |
|
|
<pre>int y = sink(source().operator auto_ptr<B>());
|
| 3274 |
|
|
</pre>
|
| 3275 |
|
|
|
| 3276 |
|
|
<p>
|
| 3277 |
|
|
IMHO no one ever wrote such awkward code and the reasonable workaround for
|
| 3278 |
|
|
#1 is:
|
| 3279 |
|
|
</p>
|
| 3280 |
|
|
<pre>int y = sink( auto_ptr<B>(source()) );
|
| 3281 |
|
|
</pre>
|
| 3282 |
|
|
|
| 3283 |
|
|
<p>
|
| 3284 |
|
|
I was even more surprised to find out that after removing the obsolete
|
| 3285 |
|
|
conversion member the initialization was still ill-formed:
|
| 3286 |
|
|
int x3 = sink(dp); // #3 EDG - no suitable copy constructor
|
| 3287 |
|
|
</p>
|
| 3288 |
|
|
|
| 3289 |
|
|
<p>
|
| 3290 |
|
|
This copy initialization semantically requires copy constructor which means
|
| 3291 |
|
|
that both template conversion constructor and the auto_ptr_ref conversion
|
| 3292 |
|
|
member (20.4.5.3/3) are required which is what was explicitly forbidden in
|
| 3293 |
|
|
DR #84. This is a bit amusing case in which removing ambiguity results with
|
| 3294 |
|
|
no candidates.
|
| 3295 |
|
|
</p>
|
| 3296 |
|
|
|
| 3297 |
|
|
<p>
|
| 3298 |
|
|
I also found exception safety issue with auto_ptr related to auto_ptr_ref:
|
| 3299 |
|
|
</p>
|
| 3300 |
|
|
<pre>int f(auto_ptr<B>, std::string);
|
| 3301 |
|
|
auto_ptr<B> source2();
|
| 3302 |
|
|
|
| 3303 |
|
|
// string constructor throws while auto_ptr_ref
|
| 3304 |
|
|
// "holds" the pointer
|
| 3305 |
|
|
int x4 = f(source2(), "xyz"); // #4
|
| 3306 |
|
|
</pre>
|
| 3307 |
|
|
|
| 3308 |
|
|
<p>
|
| 3309 |
|
|
The theoretic execution sequence that will cause a leak:
|
| 3310 |
|
|
</p>
|
| 3311 |
|
|
<ol>
|
| 3312 |
|
|
<li>call auto_ptr<B>::operator auto_ptr_ref<B>()</li>
|
| 3313 |
|
|
<li>call string::string(char const*) and throw</li>
|
| 3314 |
|
|
</ol>
|
| 3315 |
|
|
|
| 3316 |
|
|
<p>
|
| 3317 |
|
|
According to 20.4.5.3/3 and 20.4.5/2 the auto_ptr_ref conversion member
|
| 3318 |
|
|
returns auto_ptr_ref<Y> that holds *this and this is another defect since
|
| 3319 |
|
|
the type of *this is auto_ptr<X> where X might be different from Y. Several
|
| 3320 |
|
|
library vendors (e.g. SGI) implement auto_ptr_ref<Y> with Y* as member which
|
| 3321 |
|
|
is much more reasonable. Other vendor implemented auto_ptr_ref as
|
| 3322 |
|
|
defectively required and it results with awkward and catastrophic code:
|
| 3323 |
|
|
int oops = sink(auto_ptr<B>(source())); // warning recursive on all control
|
| 3324 |
|
|
paths
|
| 3325 |
|
|
</p>
|
| 3326 |
|
|
|
| 3327 |
|
|
<p>
|
| 3328 |
|
|
Dave Abrahams noticed that there is no specification saying that
|
| 3329 |
|
|
auto_ptr_ref copy constructor can't throw.
|
| 3330 |
|
|
</p>
|
| 3331 |
|
|
|
| 3332 |
|
|
<p>
|
| 3333 |
|
|
My proposal comes to solve all the above issues and significantly simplify
|
| 3334 |
|
|
auto_ptr implementation. One of the fundamental requirements from auto_ptr
|
| 3335 |
|
|
is that it can be constructed in an intuitive manner (i.e. like ordinary
|
| 3336 |
|
|
pointers) but with strict ownership semantics which yield that source
|
| 3337 |
|
|
auto_ptr in initialization must be non-const. My idea is to add additional
|
| 3338 |
|
|
constructor template with sole propose to generate ill-formed, diagnostic
|
| 3339 |
|
|
required, instance for const auto_ptr arguments during instantiation of
|
| 3340 |
|
|
declaration. This special constructor will not be instantiated for other
|
| 3341 |
|
|
types which is achievable using 14.8.2/2 (SFINAE). Having this constructor
|
| 3342 |
|
|
in hand makes the constructor template<class Y> auto_ptr(auto_ptr<Y> const&)
|
| 3343 |
|
|
legitimate since the actual argument can't be const yet non const r-value
|
| 3344 |
|
|
are acceptable.
|
| 3345 |
|
|
</p>
|
| 3346 |
|
|
|
| 3347 |
|
|
<p>
|
| 3348 |
|
|
This implementation technique makes the "private auxiliary class"
|
| 3349 |
|
|
auto_ptr_ref obsolete and I found out that modern C++ compilers (e.g. EDG,
|
| 3350 |
|
|
GCC and VC) consume the new implementation as expected and allow all
|
| 3351 |
|
|
intuitive initialization and assignment cases while rejecting illegal cases
|
| 3352 |
|
|
that involve const auto_ptr arguments.
|
| 3353 |
|
|
</p>
|
| 3354 |
|
|
|
| 3355 |
|
|
<p>The proposed auto_ptr interface:</p>
|
| 3356 |
|
|
|
| 3357 |
|
|
<pre>namespace std {
|
| 3358 |
|
|
template<class X> class auto_ptr {
|
| 3359 |
|
|
public:
|
| 3360 |
|
|
typedef X element_type;
|
| 3361 |
|
|
|
| 3362 |
|
|
// 20.4.5.1 construct/copy/destroy:
|
| 3363 |
|
|
explicit auto_ptr(X* p=0) throw();
|
| 3364 |
|
|
auto_ptr(auto_ptr&) throw();
|
| 3365 |
|
|
template<class Y> auto_ptr(auto_ptr<Y> const&) throw();
|
| 3366 |
|
|
auto_ptr& operator=(auto_ptr&) throw();
|
| 3367 |
|
|
template<class Y> auto_ptr& operator=(auto_ptr<Y>) throw();
|
| 3368 |
|
|
~auto_ptr() throw();
|
| 3369 |
|
|
|
| 3370 |
|
|
// 20.4.5.2 members:
|
| 3371 |
|
|
X& operator*() const throw();
|
| 3372 |
|
|
X* operator->() const throw();
|
| 3373 |
|
|
X* get() const throw();
|
| 3374 |
|
|
X* release() throw();
|
| 3375 |
|
|
void reset(X* p=0) throw();
|
| 3376 |
|
|
|
| 3377 |
|
|
private:
|
| 3378 |
|
|
template<class U>
|
| 3379 |
|
|
auto_ptr(U& rhs, typename
|
| 3380 |
|
|
unspecified_error_on_const_auto_ptr<U>::type = 0);
|
| 3381 |
|
|
};
|
| 3382 |
|
|
}
|
| 3383 |
|
|
</pre>
|
| 3384 |
|
|
|
| 3385 |
|
|
<p>
|
| 3386 |
|
|
One compliant technique to implement the unspecified_error_on_const_auto_ptr
|
| 3387 |
|
|
helper class is using additional private auto_ptr member class template like
|
| 3388 |
|
|
the following:
|
| 3389 |
|
|
</p>
|
| 3390 |
|
|
<pre>template<typename T> struct unspecified_error_on_const_auto_ptr;
|
| 3391 |
|
|
|
| 3392 |
|
|
template<typename T>
|
| 3393 |
|
|
struct unspecified_error_on_const_auto_ptr<auto_ptr<T> const>
|
| 3394 |
|
|
{ typedef typename auto_ptr<T>::const_auto_ptr_is_not_allowed type; };
|
| 3395 |
|
|
</pre>
|
| 3396 |
|
|
|
| 3397 |
|
|
<p>
|
| 3398 |
|
|
There are other techniques to implement this helper class that might work
|
| 3399 |
|
|
better for different compliers (i.e. better diagnostics) and therefore I
|
| 3400 |
|
|
suggest defining its semantic behavior without mandating any specific
|
| 3401 |
|
|
implementation. IMO, and I didn't found any compiler that thinks otherwise,
|
| 3402 |
|
|
14.7.1/5 doesn't theoretically defeat the suggested technique but I suggest
|
| 3403 |
|
|
verifying this with core language experts.
|
| 3404 |
|
|
</p>
|
| 3405 |
|
|
|
| 3406 |
|
|
<p><b>Further changes in standard text:</b></p>
|
| 3407 |
|
|
<p>Remove section 20.4.5.3</p>
|
| 3408 |
|
|
|
| 3409 |
|
|
<p>Change 20.4.5/2 to read something like:
|
| 3410 |
|
|
Initializing auto_ptr<X> from const auto_ptr<Y> will result with unspecified
|
| 3411 |
|
|
ill-formed declaration that will require unspecified diagnostic.</p>
|
| 3412 |
|
|
|
| 3413 |
|
|
<p>Change 20.4.5.1/4,5,6 to read:</p>
|
| 3414 |
|
|
|
| 3415 |
|
|
<pre>template<class Y> auto_ptr(auto_ptr<Y> const& a) throw();</pre>
|
| 3416 |
|
|
<p> 4 Requires: Y* can be implicitly converted to X*.</p>
|
| 3417 |
|
|
<p> 5 Effects: Calls const_cast<auto_ptr<Y>&>(a).release().</p>
|
| 3418 |
|
|
<p> 6 Postconditions: *this holds the pointer returned from a.release().</p>
|
| 3419 |
|
|
|
| 3420 |
|
|
<p>Change 20.4.5.1/10</p>
|
| 3421 |
|
|
<pre>template<class Y> auto_ptr& operator=(auto_ptr<Y> a) throw();
|
| 3422 |
|
|
</pre>
|
| 3423 |
|
|
<p>
|
| 3424 |
|
|
10 Requires: Y* can be implicitly converted to X*. The expression delete
|
| 3425 |
|
|
get() is well formed.
|
| 3426 |
|
|
</p>
|
| 3427 |
|
|
|
| 3428 |
|
|
<p>LWG TC DR #127 is obsolete.</p>
|
| 3429 |
|
|
|
| 3430 |
|
|
<p>
|
| 3431 |
|
|
Notice that the copy constructor and copy assignment operator should remain
|
| 3432 |
|
|
as before and accept non-const auto_ptr& since they have effect on the form
|
| 3433 |
|
|
of the implicitly declared copy constructor and copy assignment operator of
|
| 3434 |
|
|
class that contains auto_ptr as member per 12.8/5,10:
|
| 3435 |
|
|
</p>
|
| 3436 |
|
|
<pre>struct X {
|
| 3437 |
|
|
// implicit X(X&)
|
| 3438 |
|
|
// implicit X& operator=(X&)
|
| 3439 |
|
|
auto_ptr<D> aptr_;
|
| 3440 |
|
|
};
|
| 3441 |
|
|
</pre>
|
| 3442 |
|
|
|
| 3443 |
|
|
<p>
|
| 3444 |
|
|
In most cases this indicates about sloppy programming but preserves the
|
| 3445 |
|
|
current auto_ptr behavior.
|
| 3446 |
|
|
</p>
|
| 3447 |
|
|
|
| 3448 |
|
|
<p>
|
| 3449 |
|
|
Dave Abrahams encouraged me to suggest fallback implementation in case that
|
| 3450 |
|
|
my suggestion that involves removing of auto_ptr_ref will not be accepted.
|
| 3451 |
|
|
In this case removing the obsolete conversion member to auto_ptr<Y> and
|
| 3452 |
|
|
20.4.5.3/4,5 is still required in order to eliminate ambiguity in legal
|
| 3453 |
|
|
cases. The two constructors that I suggested will co exist with the current
|
| 3454 |
|
|
members but will make auto_ptr_ref obsolete in initialization contexts.
|
| 3455 |
|
|
auto_ptr_ref will be effective in assignment contexts as suggested in DR
|
| 3456 |
|
|
#127 and I can't see any serious exception safety issues in those cases
|
| 3457 |
|
|
(although it's possible to synthesize such). auto_ptr_ref<X> semantics will
|
| 3458 |
|
|
have to be revised to say that it strictly holds pointer of type X and not
|
| 3459 |
|
|
reference to an auto_ptr for the favor of cases in which auto_ptr_ref<Y> is
|
| 3460 |
|
|
constructed from auto_ptr<X> in which X is different from Y (i.e. assignment
|
| 3461 |
|
|
from r-value derived to base).
|
| 3462 |
|
|
</p>
|
| 3463 |
|
|
|
| 3464 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3465 |
|
|
<p><i>[Redmond: punt for the moment. We haven't decided yet whether we
|
| 3466 |
|
|
want to fix auto_ptr for C++-0x, or remove it and replace it with
|
| 3467 |
|
|
move_ptr and unique_ptr.]</i></p>
|
| 3468 |
|
|
<hr>
|
| 3469 |
|
|
<a name="466"><h3>466. basic_string ctor should prevent null pointer error</h3></a><p><b>Section:</b> 21.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.cons"> [lib.string.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Daniel Frey <b>Date:</b> 10 Jun 2004</p>
|
| 3470 |
|
|
<p>
|
| 3471 |
|
|
Today, my colleagues and me wasted a lot of time. After some time, I
|
| 3472 |
|
|
found the problem. It could be reduced to the following short example:
|
| 3473 |
|
|
</p>
|
| 3474 |
|
|
|
| 3475 |
|
|
<pre> #include <string>
|
| 3476 |
|
|
int main() { std::string( 0 ); }
|
| 3477 |
|
|
</pre>
|
| 3478 |
|
|
|
| 3479 |
|
|
<p>The problem is that the tested compilers (GCC 2.95.2, GCC 3.3.1 and
|
| 3480 |
|
|
Comeau online) compile the above without errors or warnings! The
|
| 3481 |
|
|
programs (at least for the GCC) resulted in a SEGV.</p>
|
| 3482 |
|
|
|
| 3483 |
|
|
<p>I know that the standard explicitly states that the ctor of string
|
| 3484 |
|
|
requires a char* which is not zero. STLs could easily detect the above
|
| 3485 |
|
|
case with a private ctor for basic_string which takes a single 'int'
|
| 3486 |
|
|
argument. This would catch the above code at compile time and would not
|
| 3487 |
|
|
ambiguate any other legal ctors.</p>
|
| 3488 |
|
|
|
| 3489 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3490 |
|
|
<p><i>[Redmond: No great enthusiasm for doing this. If we do,
|
| 3491 |
|
|
however, we want to do it for all places that take <tt>charT*</tt>
|
| 3492 |
|
|
pointers, not just the single-argument constructor. The other
|
| 3493 |
|
|
question is whether we want to catch this at compile time (in which
|
| 3494 |
|
|
case we catch the error of a literal 0, but not an expression whose
|
| 3495 |
|
|
value is a null pointer), at run time, or both.]</i></p>
|
| 3496 |
|
|
|
| 3497 |
|
|
<hr>
|
| 3498 |
|
|
<a name="470"><h3>470. accessing containers from their elements' special functions</h3></a><p><b>Section:</b> 23 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.containers"> [lib.containers]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 Jun 2004</p>
|
| 3499 |
|
|
|
| 3500 |
|
|
<p>
|
| 3501 |
|
|
The standard doesn't prohibit the destructors (or any other special
|
| 3502 |
|
|
functions) of containers' elements invoked from a member function
|
| 3503 |
|
|
of the container from "recursively" calling the same (or any other)
|
| 3504 |
|
|
member function on the same container object, potentially while the
|
| 3505 |
|
|
container is in an intermediate state, or even changing the state
|
| 3506 |
|
|
of the container object while it is being modified. This may result
|
| 3507 |
|
|
in some surprising (i.e., undefined) behavior.
|
| 3508 |
|
|
</p>
|
| 3509 |
|
|
|
| 3510 |
|
|
<p>Read email thread starting with c++std-lib-13637 for more.</p>
|
| 3511 |
|
|
|
| 3512 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3513 |
|
|
|
| 3514 |
|
|
<p>Add to Container Requirements the following new paragraph:</p>
|
| 3515 |
|
|
|
| 3516 |
|
|
<pre> Unless otherwise specified, the behavior of a program that
|
| 3517 |
|
|
invokes a container member function f from a member function
|
| 3518 |
|
|
g of the container's value_type on a container object c that
|
| 3519 |
|
|
called g from its mutating member function h, is undefined.
|
| 3520 |
|
|
I.e., if v is an element of c, directly or indirectly calling
|
| 3521 |
|
|
c.h() from v.g() called from c.f(), is undefined.
|
| 3522 |
|
|
</pre>
|
| 3523 |
|
|
|
| 3524 |
|
|
<p><i>[Redmond: This is a real issue, but it's probably a clause 17
|
| 3525 |
|
|
issue, not clause 23. We get the same issue, for example, if we
|
| 3526 |
|
|
try to destroy a stream from one of the stream's callback functions.]</i></p>
|
| 3527 |
|
|
|
| 3528 |
|
|
|
| 3529 |
|
|
<hr>
|
| 3530 |
|
|
<a name="471"><h3>471. result of what() implementation-defined</h3></a><p><b>Section:</b> 18.6.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.exception"> [lib.exception]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 Jun 2004</p>
|
| 3531 |
|
|
|
| 3532 |
|
|
<p>[lib.exception] specifies the following:</p>
|
| 3533 |
|
|
<pre> exception (const exception&) throw();
|
| 3534 |
|
|
exception& operator= (const exception&) throw();
|
| 3535 |
|
|
|
| 3536 |
|
|
-4- Effects: Copies an exception object.
|
| 3537 |
|
|
-5- Notes: The effects of calling what() after assignment
|
| 3538 |
|
|
are implementation-defined.
|
| 3539 |
|
|
</pre>
|
| 3540 |
|
|
|
| 3541 |
|
|
<p>
|
| 3542 |
|
|
First, does the Note only apply to the assignment operator? If so,
|
| 3543 |
|
|
what are the effects of calling what() on a copy of an object? Is
|
| 3544 |
|
|
the returned pointer supposed to point to an identical copy of
|
| 3545 |
|
|
the NTBS returned by what() called on the original object or not?
|
| 3546 |
|
|
</p>
|
| 3547 |
|
|
|
| 3548 |
|
|
<p>
|
| 3549 |
|
|
Second, is this Note intended to extend to all the derived classes
|
| 3550 |
|
|
in section 19? I.e., does the standard provide any guarantee for
|
| 3551 |
|
|
the effects of what() called on a copy of any of the derived class
|
| 3552 |
|
|
described in section 19?
|
| 3553 |
|
|
</p>
|
| 3554 |
|
|
|
| 3555 |
|
|
<p>
|
| 3556 |
|
|
Finally, if the answer to the first question is no, I believe it
|
| 3557 |
|
|
constitutes a defect since throwing an exception object typically
|
| 3558 |
|
|
implies invoking the copy ctor on the object. If the answer is yes,
|
| 3559 |
|
|
then I believe the standard ought to be clarified to spell out
|
| 3560 |
|
|
exactly what the effects are on the copy (i.e., after the copy
|
| 3561 |
|
|
ctor was called).
|
| 3562 |
|
|
</p>
|
| 3563 |
|
|
|
| 3564 |
|
|
<p><i>[Redmond: Yes, this is fuzzy. The issue of derived classes is
|
| 3565 |
|
|
fuzzy too.]</i></p>
|
| 3566 |
|
|
|
| 3567 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3568 |
|
|
<hr>
|
| 3569 |
|
|
<a name="473"><h3>473. underspecified ctype calls</h3></a><p><b>Section:</b> 22.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.ctype"> [lib.locale.ctype]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 1 Jul 2004</p>
|
| 3570 |
|
|
<p>
|
| 3571 |
|
|
Most ctype member functions come in two forms: one that operates
|
| 3572 |
|
|
on a single character at a time and another form that operates
|
| 3573 |
|
|
on a range of characters. Both forms are typically described by
|
| 3574 |
|
|
a single Effects and/or Returns clause.
|
| 3575 |
|
|
</p>
|
| 3576 |
|
|
<p>
|
| 3577 |
|
|
The Returns clause of each of the single-character non-virtual forms
|
| 3578 |
|
|
suggests that the function calls the corresponding single character
|
| 3579 |
|
|
virtual function, and that the array form calls the corresponding
|
| 3580 |
|
|
virtual array form. Neither of the two forms of each virtual member
|
| 3581 |
|
|
function is required to be implemented in terms of the other.
|
| 3582 |
|
|
</p>
|
| 3583 |
|
|
<p>
|
| 3584 |
|
|
There are three problems:
|
| 3585 |
|
|
</p>
|
| 3586 |
|
|
<p>
|
| 3587 |
|
|
1. One is that while the standard does suggest that each non-virtual
|
| 3588 |
|
|
member function calls the corresponding form of the virtual function,
|
| 3589 |
|
|
it doesn't actually explicitly require it.
|
| 3590 |
|
|
</p>
|
| 3591 |
|
|
<p>
|
| 3592 |
|
|
Implementations that cache results from some of the virtual member
|
| 3593 |
|
|
functions for some or all values of their arguments might want to
|
| 3594 |
|
|
call the array form from the non-array form the first time to fill
|
| 3595 |
|
|
the cache and avoid any or most subsequent virtual calls. Programs
|
| 3596 |
|
|
that rely on each form of the virtual function being called from
|
| 3597 |
|
|
the corresponding non-virtual function will see unexpected behavior
|
| 3598 |
|
|
when using such implementations.
|
| 3599 |
|
|
</p>
|
| 3600 |
|
|
<p>
|
| 3601 |
|
|
2. The second problem is that either form of each of the virtual
|
| 3602 |
|
|
functions can be overridden by a user-defined function in a derived
|
| 3603 |
|
|
class to return a value that is different from the one produced by
|
| 3604 |
|
|
the virtual function of the alternate form that has not been
|
| 3605 |
|
|
overriden.
|
| 3606 |
|
|
</p>
|
| 3607 |
|
|
<p>
|
| 3608 |
|
|
Thus, it might be possible for, say, ctype::widen(c) to return one
|
| 3609 |
|
|
value, while for ctype::widen(&c, &c + 1, &wc) to set
|
| 3610 |
|
|
wc to another value. This is almost certainly not intended. Both
|
| 3611 |
|
|
forms of every function should be required to return the same result
|
| 3612 |
|
|
for the same character, otherwise the same program using an
|
| 3613 |
|
|
implementation that calls one form of the functions will behave
|
| 3614 |
|
|
differently than when using another implementation that calls the
|
| 3615 |
|
|
other form of the function "under the hood."
|
| 3616 |
|
|
</p>
|
| 3617 |
|
|
<p>
|
| 3618 |
|
|
3. The last problem is that the standard text fails to specify whether
|
| 3619 |
|
|
one form of any of the virtual functions is permitted to be implemented
|
| 3620 |
|
|
in terms of the other form or not, and if so, whether it is required
|
| 3621 |
|
|
or permitted to call the overridden virtual function or not.
|
| 3622 |
|
|
</p>
|
| 3623 |
|
|
<p>
|
| 3624 |
|
|
Thus, a program that overrides one of the virtual functions so that
|
| 3625 |
|
|
it calls the other form which then calls the base member might end
|
| 3626 |
|
|
up in an infinite loop if the called form of the base implementation
|
| 3627 |
|
|
of the function in turn calls the other form.
|
| 3628 |
|
|
</p>
|
| 3629 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3630 |
|
|
|
| 3631 |
|
|
<p>
|
| 3632 |
|
|
Lillehammer: Part of this isn't a real problem. We already talk about
|
| 3633 |
|
|
caching. 22.1.1/6 But part is a real problem. ctype virtuals may call
|
| 3634 |
|
|
each other, so users don't know which ones to override to avoid avoid
|
| 3635 |
|
|
infinite loops.</p>
|
| 3636 |
|
|
|
| 3637 |
|
|
<p>This is a problem for all facet virtuals, not just ctype virtuals,
|
| 3638 |
|
|
so we probably want a blanket statement in clause 22 for all
|
| 3639 |
|
|
facets. The LWG is leaning toward a blanket prohibition, that a
|
| 3640 |
|
|
facet's virtuals may never call each other. We might want to do that
|
| 3641 |
|
|
in clause 27 too, for that matter. A review is necessary. Bill will
|
| 3642 |
|
|
provide wording.</p>
|
| 3643 |
|
|
<hr>
|
| 3644 |
|
|
<a name="475"><h3>475. May the function object passed to for_each modify the elements of the iterated sequence?</h3></a><p><b>Section:</b> 25.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.foreach"> [lib.alg.foreach]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Stephan T. Lavavej, Jaakko Jarvi <b>Date:</b> 9 Jul 2004</p>
|
| 3645 |
|
|
<p>
|
| 3646 |
|
|
It is not clear whether the function object passed to for_each is allowed to
|
| 3647 |
|
|
modify the elements of the sequence being iterated over.
|
| 3648 |
|
|
</p>
|
| 3649 |
|
|
|
| 3650 |
|
|
<p>
|
| 3651 |
|
|
for_each is classified without explanation in [lib.alg.nonmodifying], "25.1
|
| 3652 |
|
|
Non-modifying sequence operations". 'Non-modifying sequence operation' is
|
| 3653 |
|
|
never defined.
|
| 3654 |
|
|
</p>
|
| 3655 |
|
|
|
| 3656 |
|
|
<p>
|
| 3657 |
|
|
25(5) says: "If an algorithm's Effects section says that a value pointed to
|
| 3658 |
|
|
by any iterator passed as an argument is modified, then that algorithm has
|
| 3659 |
|
|
an additional type requirement: The type of that argument shall satisfy the
|
| 3660 |
|
|
requirements of a mutable iterator (24.1)."
|
| 3661 |
|
|
</p>
|
| 3662 |
|
|
|
| 3663 |
|
|
<p>for_each's Effects section does not mention whether arguments can be
|
| 3664 |
|
|
modified:</p>
|
| 3665 |
|
|
|
| 3666 |
|
|
<blockquote>
|
| 3667 |
|
|
"Effects: Applies f to the result of dereferencing every iterator in the
|
| 3668 |
|
|
range [first, last), starting from first and proceeding to last - 1."
|
| 3669 |
|
|
</blockquote>
|
| 3670 |
|
|
|
| 3671 |
|
|
<p>
|
| 3672 |
|
|
Every other algorithm in [lib.alg.nonmodifying] is "really" non-modifying in
|
| 3673 |
|
|
the sense that neither the algorithms themselves nor the function objects
|
| 3674 |
|
|
passed to the algorithms may modify the sequences or elements in any way.
|
| 3675 |
|
|
This DR affects only for_each.
|
| 3676 |
|
|
</p>
|
| 3677 |
|
|
|
| 3678 |
|
|
<p>
|
| 3679 |
|
|
We suspect that for_each's classification in "non-modifying sequence
|
| 3680 |
|
|
operations" means that the algorithm itself does not inherently modify the
|
| 3681 |
|
|
sequence or the elements in the sequence, but that the function object
|
| 3682 |
|
|
passed to it may modify the elements it operates on.
|
| 3683 |
|
|
</p>
|
| 3684 |
|
|
|
| 3685 |
|
|
<p>
|
| 3686 |
|
|
The original STL document by Stepanov and Lee explicitly prohibited the
|
| 3687 |
|
|
function object from modifying its argument.
|
| 3688 |
|
|
The "obvious" implementation of for_each found in several standard library
|
| 3689 |
|
|
implementations, however, does not impose this restriction.
|
| 3690 |
|
|
As a result, we suspect that the use of for_each with function objects that modify
|
| 3691 |
|
|
their arguments is wide-spread.
|
| 3692 |
|
|
If the restriction was reinstated, all such code would become non-conforming.
|
| 3693 |
|
|
Further, none of the other algorithms in the Standard
|
| 3694 |
|
|
could serve the purpose of for_each (transform does not guarantee the order in
|
| 3695 |
|
|
which its function object is called).
|
| 3696 |
|
|
</p>
|
| 3697 |
|
|
|
| 3698 |
|
|
<p>
|
| 3699 |
|
|
We suggest that the standard be clarified to explicitly allow the function object
|
| 3700 |
|
|
passed to for_each modify its argument.</p>
|
| 3701 |
|
|
|
| 3702 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3703 |
|
|
<p>Add a nonnormative note to the Effects in 25.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.foreach"> [lib.alg.foreach]</a>: If
|
| 3704 |
|
|
the type of 'first' satisfies the requirements of a mutable iterator,
|
| 3705 |
|
|
'f' may apply nonconstant functions through the dereferenced iterators
|
| 3706 |
|
|
passed to it.
|
| 3707 |
|
|
</p>
|
| 3708 |
|
|
|
| 3709 |
|
|
<p><b>Rationale:</b></p>
|
| 3710 |
|
|
<p>The LWG believes that nothing in the standard prohibits function
|
| 3711 |
|
|
objects that modify the sequence elements. The problem is that
|
| 3712 |
|
|
for_each is in a secion entitled "nonmutating algorithms", and the
|
| 3713 |
|
|
title may be confusing. A nonnormative note should clarify that.</p>
|
| 3714 |
|
|
<hr>
|
| 3715 |
|
|
<a name="478"><h3>478. Should forward iterator requirements table have a line for r->m?</h3></a><p><b>Section:</b> 24.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.forward.iterators"> [lib.forward.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 11 Jul 2004</p>
|
| 3716 |
|
|
<p>
|
| 3717 |
|
|
The Forward Iterator requirements table contains the following:
|
| 3718 |
|
|
</p>
|
| 3719 |
|
|
<pre> expression return type operational precondition
|
| 3720 |
|
|
semantics
|
| 3721 |
|
|
========== ================== =========== ==========================
|
| 3722 |
|
|
a->m U& if X is mutable, (*a).m pre: (*a).m is well-defined.
|
| 3723 |
|
|
otherwise const U&
|
| 3724 |
|
|
|
| 3725 |
|
|
r->m U& (*r).m pre: (*r).m is well-defined.
|
| 3726 |
|
|
</pre>
|
| 3727 |
|
|
|
| 3728 |
|
|
<p>The second line may be unnecessary. Paragraph 11 of
|
| 3729 |
|
|
[lib.iterator.requirements] says:
|
| 3730 |
|
|
</p>
|
| 3731 |
|
|
|
| 3732 |
|
|
<blockquote>
|
| 3733 |
|
|
In the following sections, a and b denote values of type const X, n
|
| 3734 |
|
|
denotes a value of the difference type Distance, u, tmp, and m
|
| 3735 |
|
|
denote identifiers, r denotes a value of X&, t denotes a value of
|
| 3736 |
|
|
value type T, o denotes a value of some type that is writable to
|
| 3737 |
|
|
the output iterator.
|
| 3738 |
|
|
</blockquote>
|
| 3739 |
|
|
|
| 3740 |
|
|
<p>
|
| 3741 |
|
|
Because operators can be overloaded on an iterator's const-ness, the
|
| 3742 |
|
|
current requirements allow iterators to make many of the operations
|
| 3743 |
|
|
specified using the identifiers a and b invalid for non-const
|
| 3744 |
|
|
iterators.</p>
|
| 3745 |
|
|
|
| 3746 |
|
|
<p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#477">477</a></p>
|
| 3747 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3748 |
|
|
|
| 3749 |
|
|
<p>Remove the "r->m" line from the Forward Iterator requirements
|
| 3750 |
|
|
table. Change</p>
|
| 3751 |
|
|
<blockquote>
|
| 3752 |
|
|
"const X"
|
| 3753 |
|
|
</blockquote>
|
| 3754 |
|
|
|
| 3755 |
|
|
<p> to </p>
|
| 3756 |
|
|
|
| 3757 |
|
|
<blockquote>
|
| 3758 |
|
|
"X or const X"
|
| 3759 |
|
|
</blockquote>
|
| 3760 |
|
|
|
| 3761 |
|
|
<p>in paragraph 11 of [lib.iterator.requirements].</p>
|
| 3762 |
|
|
|
| 3763 |
|
|
|
| 3764 |
|
|
<p><b>Rationale:</b></p>
|
| 3765 |
|
|
<p>
|
| 3766 |
|
|
This is a defect because it constrains an lvalue to returning a modifiable lvalue.
|
| 3767 |
|
|
</p>
|
| 3768 |
|
|
<hr>
|
| 3769 |
|
|
<a name="479"><h3>479. Container requirements and placement new</h3></a><p><b>Section:</b> 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Herb Sutter <b>Date:</b> 1 Aug 2004</p>
|
| 3770 |
|
|
<p>Nothing in the standard appears to make this program ill-formed:</p>
|
| 3771 |
|
|
|
| 3772 |
|
|
<pre> struct C {
|
| 3773 |
|
|
void* operator new( size_t s ) { return ::operator new( s ); }
|
| 3774 |
|
|
// NOTE: this hides in-place and nothrow new
|
| 3775 |
|
|
};
|
| 3776 |
|
|
|
| 3777 |
|
|
int main() {
|
| 3778 |
|
|
vector<C> v;
|
| 3779 |
|
|
v.push_back( C() );
|
| 3780 |
|
|
}
|
| 3781 |
|
|
</pre>
|
| 3782 |
|
|
|
| 3783 |
|
|
<p>Is that intentional? We should clarify whether or not we intended
|
| 3784 |
|
|
to require containers to support types that define their own special
|
| 3785 |
|
|
versions of <tt>operator new</tt>.</p>
|
| 3786 |
|
|
|
| 3787 |
|
|
<p><i>[
|
| 3788 |
|
|
Lillehammer: A container will definitely never use this overridden
|
| 3789 |
|
|
operator new, but whether it will fail to compile is unclear from the
|
| 3790 |
|
|
standard. Are containers supposed to use qualified or unqualified
|
| 3791 |
|
|
placement new? 20.4.1.1 is somewhat relevant, but the standard
|
| 3792 |
|
|
doesn't make it completely clear whether containers have to use
|
| 3793 |
|
|
Allocator::construct(). If containers don't use it, the details of how
|
| 3794 |
|
|
containers use placement new are unspecified. That is the real bug,
|
| 3795 |
|
|
but it needs to be fixed as part of the allocator overhaul. Weak
|
| 3796 |
|
|
support that the eventual solution should make this code well formed.
|
| 3797 |
|
|
]</i></p>
|
| 3798 |
|
|
|
| 3799 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3800 |
|
|
<hr>
|
| 3801 |
|
|
<a name="482"><h3>482. Swapping pairs</h3></a><p><b>Section:</b> 20.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.pairs"> [lib.pairs]</a>, 25.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.swap"> [lib.alg.swap]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 14 Sep 2004</p>
|
| 3802 |
|
|
<p>(Based on recent comp.std.c++ discussion)</p>
|
| 3803 |
|
|
|
| 3804 |
|
|
<p>Pair (and tuple) should specialize std::swap to work in terms of
|
| 3805 |
|
|
std::swap on their components. For example, there's no obvious reason
|
| 3806 |
|
|
why swapping two objects of type pair<vector<int>,
|
| 3807 |
|
|
list<double> > should not take O(1).</p>
|
| 3808 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3809 |
|
|
|
| 3810 |
|
|
|
| 3811 |
|
|
<p><i>[Lillehammer: We agree it should be swappable. Howard will
|
| 3812 |
|
|
provide wording.]</i></p>
|
| 3813 |
|
|
|
| 3814 |
|
|
<hr>
|
| 3815 |
|
|
<a name="484"><h3>484. Convertible to T</h3></a><p><b>Section:</b> 24.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.input.iterators"> [lib.input.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Chris <b>Date:</b> 16 Sep 2004</p>
|
| 3816 |
|
|
<p>From comp.std.c++:</p>
|
| 3817 |
|
|
|
| 3818 |
|
|
<p>
|
| 3819 |
|
|
I note that given an input iterator a for type T,
|
| 3820 |
|
|
then *a only has to be "convertable to T", not actually of type T.
|
| 3821 |
|
|
</p>
|
| 3822 |
|
|
|
| 3823 |
|
|
<p>Firstly, I can't seem to find an exact definition of "convertable to T".
|
| 3824 |
|
|
While I assume it is the obvious definition (an implicit conversion), I
|
| 3825 |
|
|
can't find an exact definition. Is there one?</p>
|
| 3826 |
|
|
|
| 3827 |
|
|
<p>Slightly more worryingly, there doesn't seem to be any restriction on
|
| 3828 |
|
|
the this type, other than it is "convertable to T". Consider two input
|
| 3829 |
|
|
iterators a and b. I would personally assume that most people would
|
| 3830 |
|
|
expect *a==*b would perform T(*a)==T(*b), however it doesn't seem that
|
| 3831 |
|
|
the standard requires that, and that whatever type *a is (call it U)
|
| 3832 |
|
|
could have == defined on it with totally different symantics and still
|
| 3833 |
|
|
be a valid inputer iterator.</p>
|
| 3834 |
|
|
|
| 3835 |
|
|
<p>Is this a correct reading? When using input iterators should I write
|
| 3836 |
|
|
T(*a) all over the place to be sure that the object i'm using is the
|
| 3837 |
|
|
class I expect?</p>
|
| 3838 |
|
|
|
| 3839 |
|
|
<p>This is especially a nuisance for operations that are defined to be
|
| 3840 |
|
|
"convertible to bool". (This is probably allowed so that
|
| 3841 |
|
|
implementations could return say an int and avoid an unnessary
|
| 3842 |
|
|
conversion. However all implementations I have seen simply return a
|
| 3843 |
|
|
bool anyway. Typical implemtations of STL algorithms just write
|
| 3844 |
|
|
things like <tt>while(a!=b && *a!=0)</tt>. But strictly
|
| 3845 |
|
|
speaking, there are lots of types that are convertible to T but
|
| 3846 |
|
|
that also overload the appropriate operators so this doesn't behave
|
| 3847 |
|
|
as expected.</p>
|
| 3848 |
|
|
|
| 3849 |
|
|
<p>If we want to make code like this legal (which most people seem to
|
| 3850 |
|
|
expect), then we'll need to tighten up what we mean by "convertible
|
| 3851 |
|
|
to T".</p>
|
| 3852 |
|
|
|
| 3853 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3854 |
|
|
<p><i>[Lillehammer: The first part is NAD, since "convertible" is
|
| 3855 |
|
|
well-defined in core. The second part is basically about pathological
|
| 3856 |
|
|
overloads. It's a minor problem but a real one. So leave open for
|
| 3857 |
|
|
now, hope we solve it as part of iterator redesign.]</i></p>
|
| 3858 |
|
|
<hr>
|
| 3859 |
|
|
<a name="485"><h3>485. output iterator insufficently constrained</h3></a><p><b>Section:</b> 24.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.output.iterators"> [lib.output.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Chris <b>Date:</b> 13 Oct 2004</p>
|
| 3860 |
|
|
<p>
|
| 3861 |
|
|
The note on 24.1.2 Output iterators insufficently limits what can be
|
| 3862 |
|
|
performed on output iterators. While it requires that each iterator is
|
| 3863 |
|
|
progressed through only once and that each iterator is written to only
|
| 3864 |
|
|
once, it does not require the following things:</p>
|
| 3865 |
|
|
|
| 3866 |
|
|
<p>Note: Here it is assumed that x is an output iterator of type X which
|
| 3867 |
|
|
has not yet been assigned to.</p>
|
| 3868 |
|
|
|
| 3869 |
|
|
<p>a) That each value of the output iterator is written to:
|
| 3870 |
|
|
The standard allows:
|
| 3871 |
|
|
++x; ++x; ++x;
|
| 3872 |
|
|
</p>
|
| 3873 |
|
|
|
| 3874 |
|
|
<p>
|
| 3875 |
|
|
b) That assignments to the output iterator are made in order
|
| 3876 |
|
|
X a(x); ++a; *a=1; *x=2; is allowed
|
| 3877 |
|
|
</p>
|
| 3878 |
|
|
|
| 3879 |
|
|
<p>
|
| 3880 |
|
|
c) Chains of output iterators cannot be constructed:
|
| 3881 |
|
|
X a(x); ++a; X b(a); ++b; X c(b); ++c; is allowed, and under the current
|
| 3882 |
|
|
wording (I believe) x,a,b,c could be written to in any order.
|
| 3883 |
|
|
</p>
|
| 3884 |
|
|
|
| 3885 |
|
|
<p>I do not believe this was the intension of the standard?</p>
|
| 3886 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3887 |
|
|
<p><i>[Lillehammer: Real issue. There are lots of constraints we
|
| 3888 |
|
|
intended but didn't specify. Should be solved as part of iterator
|
| 3889 |
|
|
redesign.]</i></p>
|
| 3890 |
|
|
<hr>
|
| 3891 |
|
|
<a name="488"><h3>488. rotate throws away useful information</h3></a><p><b>Section:</b> 25.2.10 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.rotate"> [lib.alg.rotate]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 22 Nov 2004</p>
|
| 3892 |
|
|
<p>
|
| 3893 |
|
|
rotate takes 3 iterators: first, middle and last which point into a
|
| 3894 |
|
|
sequence, and rearranges the sequence such that the subrange [middle,
|
| 3895 |
|
|
last) is now at the beginning of the sequence and the subrange [first,
|
| 3896 |
|
|
middle) follows. The return type is void.
|
| 3897 |
|
|
</p>
|
| 3898 |
|
|
|
| 3899 |
|
|
<p>
|
| 3900 |
|
|
In many use cases of rotate, the client needs to know where the
|
| 3901 |
|
|
subrange [first, middle) starts after the rotate is performed. This
|
| 3902 |
|
|
might look like:
|
| 3903 |
|
|
</p>
|
| 3904 |
|
|
<pre> rotate(first, middle, last);
|
| 3905 |
|
|
Iterator i = advance(first, distance(middle, last));
|
| 3906 |
|
|
</pre>
|
| 3907 |
|
|
|
| 3908 |
|
|
<p>
|
| 3909 |
|
|
Unless the iterators are random access, the computation to find the
|
| 3910 |
|
|
start of the subrange [first, middle) has linear complexity. However,
|
| 3911 |
|
|
it is not difficult for rotate to return this information with
|
| 3912 |
|
|
negligible additional computation expense. So the client could code:
|
| 3913 |
|
|
</p>
|
| 3914 |
|
|
<pre> Iterator i = rotate(first, middle, last);
|
| 3915 |
|
|
</pre>
|
| 3916 |
|
|
|
| 3917 |
|
|
<p>
|
| 3918 |
|
|
and the resulting program becomes significantly more efficient.
|
| 3919 |
|
|
</p>
|
| 3920 |
|
|
|
| 3921 |
|
|
<p>
|
| 3922 |
|
|
While the backwards compatibility hit with this change is not zero, it
|
| 3923 |
|
|
is very small (similar to that of lwg <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">130</a>), and there is
|
| 3924 |
|
|
a significant benefit to the change.
|
| 3925 |
|
|
</p>
|
| 3926 |
|
|
|
| 3927 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 3928 |
|
|
<p>In 25p2, change:</p>
|
| 3929 |
|
|
<pre> template<class ForwardIterator>
|
| 3930 |
|
|
void rotate(ForwardIterator first, ForwardIterator middle,
|
| 3931 |
|
|
ForwardIterator last);
|
| 3932 |
|
|
</pre>
|
| 3933 |
|
|
|
| 3934 |
|
|
<p>to:</p>
|
| 3935 |
|
|
|
| 3936 |
|
|
<pre> template<class ForwardIterator>
|
| 3937 |
|
|
ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
|
| 3938 |
|
|
ForwardIterator last);
|
| 3939 |
|
|
</pre>
|
| 3940 |
|
|
|
| 3941 |
|
|
<p>In 25.2.10, change:</p>
|
| 3942 |
|
|
|
| 3943 |
|
|
<pre> template<class ForwardIterator>
|
| 3944 |
|
|
void rotate(ForwardIterator first, ForwardIterator middle,
|
| 3945 |
|
|
ForwardIterator last);
|
| 3946 |
|
|
</pre>
|
| 3947 |
|
|
|
| 3948 |
|
|
<p>to:</p>
|
| 3949 |
|
|
|
| 3950 |
|
|
<pre> template<class ForwardIterator>
|
| 3951 |
|
|
ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
|
| 3952 |
|
|
ForwardIterator last);
|
| 3953 |
|
|
</pre>
|
| 3954 |
|
|
|
| 3955 |
|
|
<p>In 25.2.10 insert a new paragraph after p1:</p>
|
| 3956 |
|
|
|
| 3957 |
|
|
<blockquote>
|
| 3958 |
|
|
<p><b>Returns</b>: <tt>first + (last - middle)</tt>.</p>
|
| 3959 |
|
|
</blockquote>
|
| 3960 |
|
|
|
| 3961 |
|
|
<p><i>[
|
| 3962 |
|
|
The LWG agrees with this idea, but has one quibble: we want to make
|
| 3963 |
|
|
sure not to give the impression that the function "advance" is
|
| 3964 |
|
|
actually called, just that the nth iterator is returned. (Calling
|
| 3965 |
|
|
advance is observable behavior, since users can specialize it for
|
| 3966 |
|
|
their own iterators.) Howard will provide wording.
|
| 3967 |
|
|
]</i></p>
|
| 3968 |
|
|
|
| 3969 |
|
|
<p><i>[Howard provided wording for mid-meeting-mailing Jun. 2005.]</i></p>
|
| 3970 |
|
|
|
| 3971 |
|
|
<hr>
|
| 3972 |
|
|
<a name="492"><h3>492. Invalid iterator arithmetic expressions</h3></a><p><b>Section:</b> 23 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.containers"> [lib.containers]</a>, 24 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterators"> [lib.iterators]</a>, 25 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Thomas Mang <b>Date:</b> 12 Dec 2004</p>
|
| 3973 |
|
|
<p>Various clauses other than clause 25 make use of iterator arithmetic not
|
| 3974 |
|
|
supported by the iterator category in question.
|
| 3975 |
|
|
Algorithms in clause 25 are exceptional because of 25 [lib.algorithms],
|
| 3976 |
|
|
paragraph 9, but this paragraph does not provide semantics to the
|
| 3977 |
|
|
expression "iterator - n", where n denotes a value of a distance type
|
| 3978 |
|
|
between iterators.</p>
|
| 3979 |
|
|
|
| 3980 |
|
|
<p>1) Examples of current wording:</p>
|
| 3981 |
|
|
|
| 3982 |
|
|
<p>Current wording outside clause 25:</p>
|
| 3983 |
|
|
|
| 3984 |
|
|
<p>
|
| 3985 |
|
|
23.2.2.4 [lib.list.ops], paragraphs 19-21: "first + 1", "(i - 1)",
|
| 3986 |
|
|
"(last - first)"
|
| 3987 |
|
|
23.3.1.1 [lib.map.cons], paragraph 4: "last - first"
|
| 3988 |
|
|
23.3.2.1 [lib.multimap.cons], paragraph 4: "last - first"
|
| 3989 |
|
|
23.3.3.1 [lib.set.cons], paragraph 4: "last - first"
|
| 3990 |
|
|
23.3.4.1 [lib.multiset.cons], paragraph 4: "last - first"
|
| 3991 |
|
|
24.4.1 [lib.reverse.iterators], paragraph 1: "(i - 1)"
|
| 3992 |
|
|
</p>
|
| 3993 |
|
|
|
| 3994 |
|
|
<p>
|
| 3995 |
|
|
[Important note: The list is not complete, just an illustration. The
|
| 3996 |
|
|
same issue might well apply to other paragraphs not listed here.]</p>
|
| 3997 |
|
|
|
| 3998 |
|
|
<p>None of these expressions is valid for the corresponding iterator
|
| 3999 |
|
|
category.</p>
|
| 4000 |
|
|
|
| 4001 |
|
|
<p>Current wording in clause 25:</p>
|
| 4002 |
|
|
|
| 4003 |
|
|
<p>
|
| 4004 |
|
|
25.1.1 [lib.alg.foreach], paragraph 1: "last - 1"
|
| 4005 |
|
|
25.1.3 [lib.alg.find.end], paragraph 2: "[first1, last1 -
|
| 4006 |
|
|
(last2-first2))"
|
| 4007 |
|
|
25.2.8 [lib.alg.unique], paragraph 1: "(i - 1)"
|
| 4008 |
|
|
25.2.8 [lib.alg.unique], paragraph 5: "(i - 1)"
|
| 4009 |
|
|
</p>
|
| 4010 |
|
|
|
| 4011 |
|
|
<p>
|
| 4012 |
|
|
However, current wording of 25 [lib.algorithms], paragraph 9 covers
|
| 4013 |
|
|
neither of these four cases:</p>
|
| 4014 |
|
|
|
| 4015 |
|
|
<p>Current wording of 25 [lib.algorithms], paragraph 9:</p>
|
| 4016 |
|
|
|
| 4017 |
|
|
<p>
|
| 4018 |
|
|
"In the description of the algorithms operator + and - are used for some
|
| 4019 |
|
|
of the iterator categories for which they do not have to be defined. In
|
| 4020 |
|
|
these cases the semantics of a+n is the same as that of</p>
|
| 4021 |
|
|
<pre>{X tmp = a;
|
| 4022 |
|
|
advance(tmp, n);
|
| 4023 |
|
|
return tmp;
|
| 4024 |
|
|
}
|
| 4025 |
|
|
</pre>
|
| 4026 |
|
|
<p>and that of b-a is the same as of return distance(a, b)"</p>
|
| 4027 |
|
|
|
| 4028 |
|
|
<p>
|
| 4029 |
|
|
This paragrpah does not take the expression "iterator - n" into account,
|
| 4030 |
|
|
where n denotes a value of a distance type between two iterators [Note:
|
| 4031 |
|
|
According to current wording, the expression "iterator - n" would be
|
| 4032 |
|
|
resolved as equivalent to "return distance(n, iterator)"]. Even if the
|
| 4033 |
|
|
expression "iterator - n" were to be reinterpreted as equivalent to
|
| 4034 |
|
|
"iterator + -n" [Note: This would imply that "a" and "b" were
|
| 4035 |
|
|
interpreted implicitly as values of iterator types, and "n" as value of
|
| 4036 |
|
|
a distance type], then 24.3.4/2 interfers because it says: "Requires: n
|
| 4037 |
|
|
may be negative only for random access and bidirectional iterators.",
|
| 4038 |
|
|
and none of the paragraphs quoted above requires the iterators on which
|
| 4039 |
|
|
the algorithms operate to be of random access or bidirectional category.
|
| 4040 |
|
|
</p>
|
| 4041 |
|
|
|
| 4042 |
|
|
<p>2) Description of intended behavior:</p>
|
| 4043 |
|
|
|
| 4044 |
|
|
<p>
|
| 4045 |
|
|
For the rest of this Defect Report, it is assumed that the expression
|
| 4046 |
|
|
"iterator1 + n" and "iterator1 - iterator2" has the semantics as
|
| 4047 |
|
|
described in current 25 [lib.algorithms], paragraph 9, but applying to
|
| 4048 |
|
|
all clauses. The expression "iterator1 - n" is equivalent to an
|
| 4049 |
|
|
result-iterator for which the expression "result-iterator + n" yields an
|
| 4050 |
|
|
iterator denoting the same position as iterator1 does. The terms
|
| 4051 |
|
|
"iterator1", "iterator2" and "result-iterator" shall denote the value of
|
| 4052 |
|
|
an iterator type, and the term "n" shall denote a value of a distance
|
| 4053 |
|
|
type between two iterators.</p>
|
| 4054 |
|
|
|
| 4055 |
|
|
<p>
|
| 4056 |
|
|
All implementations known to the author of this Defect Report comply
|
| 4057 |
|
|
with these assumptions.
|
| 4058 |
|
|
No impact on current code is expected.</p>
|
| 4059 |
|
|
|
| 4060 |
|
|
<p>3) Proposed fixes:</p>
|
| 4061 |
|
|
|
| 4062 |
|
|
|
| 4063 |
|
|
<p>Change 25 [lib.algorithms], paragraph 9 to:</p>
|
| 4064 |
|
|
|
| 4065 |
|
|
<p>
|
| 4066 |
|
|
"In the description of the algorithms operator + and - are used for some
|
| 4067 |
|
|
of the iterator categories for which they do not have to be defined. In
|
| 4068 |
|
|
this paragraph, a and b denote values of an iterator type, and n denotes
|
| 4069 |
|
|
a value of a distance type between two iterators. In these cases the
|
| 4070 |
|
|
semantics of a+n is the same as that of</p>
|
| 4071 |
|
|
<pre>{X tmp = a;
|
| 4072 |
|
|
advance(tmp, n);
|
| 4073 |
|
|
return tmp;
|
| 4074 |
|
|
}
|
| 4075 |
|
|
</pre>
|
| 4076 |
|
|
<p>,the semantics of a-n denotes the value of an iterator i for which the
|
| 4077 |
|
|
following condition holds:
|
| 4078 |
|
|
advance(i, n) == a,
|
| 4079 |
|
|
and that of b-a is the same as of
|
| 4080 |
|
|
return distance(a, b)".
|
| 4081 |
|
|
</p>
|
| 4082 |
|
|
|
| 4083 |
|
|
<p>Comments to the new wording:</p>
|
| 4084 |
|
|
|
| 4085 |
|
|
<p>
|
| 4086 |
|
|
a) The wording " In this paragraph, a and b denote values of an iterator
|
| 4087 |
|
|
type, and n denotes a value of a distance type between two iterators."
|
| 4088 |
|
|
was added so the expressions "b-a" and "a-n" are distinguished regarding
|
| 4089 |
|
|
the types of the values on which they operate.
|
| 4090 |
|
|
b) The wording ",the semantics of a-n denotes the value of an iterator i
|
| 4091 |
|
|
for which the following condition holds: advance(i, n) == a" was added
|
| 4092 |
|
|
to cover the expression 'iterator - n'. The wording "advance(i, n) == a"
|
| 4093 |
|
|
was used to avoid a dependency on the semantics of a+n, as the wording
|
| 4094 |
|
|
"i + n == a" would have implied. However, such a dependency might well
|
| 4095 |
|
|
be deserved.
|
| 4096 |
|
|
c) DR 225 is not considered in the new wording.
|
| 4097 |
|
|
</p>
|
| 4098 |
|
|
|
| 4099 |
|
|
<p>
|
| 4100 |
|
|
Proposed fixes regarding invalid iterator arithmetic expressions outside
|
| 4101 |
|
|
clause 25:</p>
|
| 4102 |
|
|
|
| 4103 |
|
|
<p>
|
| 4104 |
|
|
Either
|
| 4105 |
|
|
a) Move modified 25 [lib.algorithms], paragraph 9 (as proposed above)
|
| 4106 |
|
|
before any current invalid iterator arithmetic expression. In that case,
|
| 4107 |
|
|
the first sentence of 25 [lib.algorithms], paragraph 9, need also to be
|
| 4108 |
|
|
modified and could read: "For the rest of this International Standard,
|
| 4109 |
|
|
...." / "In the description of the following clauses including this
|
| 4110 |
|
|
...." / "In the description of the text below ..." etc. - anyways
|
| 4111 |
|
|
substituting the wording "algorithms", which is a straight reference to
|
| 4112 |
|
|
clause 25.
|
| 4113 |
|
|
In that case, 25 [lib.algorithms] paragraph 9 will certainly become
|
| 4114 |
|
|
obsolete.
|
| 4115 |
|
|
Alternatively,
|
| 4116 |
|
|
b) Add an appropiate paragraph similar to resolved 25 [lib.algorithms],
|
| 4117 |
|
|
paragraph 9, to the beginning of each clause containing invalid iterator
|
| 4118 |
|
|
arithmetic expressions.
|
| 4119 |
|
|
Alternatively,
|
| 4120 |
|
|
c) Fix each paragraph (both current wording and possible resolutions of
|
| 4121 |
|
|
DRs) containing invalid iterator arithmetic expressions separately.
|
| 4122 |
|
|
</p>
|
| 4123 |
|
|
|
| 4124 |
|
|
<p>5) References to other DRs:</p>
|
| 4125 |
|
|
|
| 4126 |
|
|
<p>
|
| 4127 |
|
|
See DR 225.
|
| 4128 |
|
|
See DR 237. The resolution could then also read "Linear in last -
|
| 4129 |
|
|
first".
|
| 4130 |
|
|
</p>
|
| 4131 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4132 |
|
|
|
| 4133 |
|
|
<p><i>[Lillehammer: Minor issue, but real. We have a blanket statement
|
| 4134 |
|
|
about this in 25/11. But (a) it should be in 17, not 25; and (b) it's
|
| 4135 |
|
|
not quite broad enough, because there are some arithmetic expressions
|
| 4136 |
|
|
it doesn't cover. Bill will provide wording.]</i></p>
|
| 4137 |
|
|
|
| 4138 |
|
|
<hr>
|
| 4139 |
|
|
<a name="495"><h3>495. Clause 22 template parameter requirements</h3></a><p><b>Section:</b> 22 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.localization"> [lib.localization]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 10 Jan 2005</p>
|
| 4140 |
|
|
<p>It appears that there are no requirements specified for many of the
|
| 4141 |
|
|
template parameters in clause 22. It looks like this issue has never
|
| 4142 |
|
|
come up, except perhaps for Facet.</p>
|
| 4143 |
|
|
|
| 4144 |
|
|
<p>Clause 22 isn't even listed in 17.3.2.1 [lib.type.descriptions],
|
| 4145 |
|
|
either, which is the wording that allows requirements on template
|
| 4146 |
|
|
parameters to be identified by name.</p>
|
| 4147 |
|
|
|
| 4148 |
|
|
<p>So one issue is that 17.3.2.1 [lib.type.descriptions] Should be
|
| 4149 |
|
|
changed to cover clause 22. A better change, which will cover us in
|
| 4150 |
|
|
the future, would be to say that it applies to all the library
|
| 4151 |
|
|
clauses. Then if a template gets added to any library clause we are
|
| 4152 |
|
|
covered.</p>
|
| 4153 |
|
|
|
| 4154 |
|
|
<p>charT, InputIterator, and other names with requirements defined
|
| 4155 |
|
|
elsewhere are fine, assuming the 17.3.2.1 [lib.type.descriptions] fix.
|
| 4156 |
|
|
But there are a few template arguments names which I don't think have
|
| 4157 |
|
|
requirements given elsewhere:</p>
|
| 4158 |
|
|
|
| 4159 |
|
|
<ul>
|
| 4160 |
|
|
<li>internT and externT. The fix is to add wording saying that internT
|
| 4161 |
|
|
and externT must meet the same requirements as template arguments
|
| 4162 |
|
|
named charT.</li>
|
| 4163 |
|
|
|
| 4164 |
|
|
<li>stateT. I'm not sure about this one. There already is some wording,
|
| 4165 |
|
|
but it seems a bit vague.</li>
|
| 4166 |
|
|
|
| 4167 |
|
|
<li>Intl. [lib.locale.moneypunct.byname] The fix for this one is to
|
| 4168 |
|
|
rename "Intl" to "International". The name is important because other
|
| 4169 |
|
|
text identifies the requirements for the name International but not
|
| 4170 |
|
|
for Intl.</li>
|
| 4171 |
|
|
</ul>
|
| 4172 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4173 |
|
|
<p>Change 17.3.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.type.descriptions"> [lib.type.descriptions]</a>, paragraph 1, from:</p>
|
| 4174 |
|
|
<blockquote>
|
| 4175 |
|
|
The Requirements subclauses may describe names that are used to
|
| 4176 |
|
|
specify constraints on template arguments.153) These names are used in
|
| 4177 |
|
|
clauses 20, 23, 25, and 26 to describe the types that may be supplied
|
| 4178 |
|
|
as arguments by a C++ program when instantiating template components
|
| 4179 |
|
|
from the library.
|
| 4180 |
|
|
</blockquote>
|
| 4181 |
|
|
<p>to:</p>
|
| 4182 |
|
|
<blockquote>
|
| 4183 |
|
|
The Requirements subclauses may describe names that are used to
|
| 4184 |
|
|
specify constraints on template arguments.153) These names are used in
|
| 4185 |
|
|
library clauses to describe the types that may be supplied as
|
| 4186 |
|
|
arguments by a C++ program when instantiating template components from
|
| 4187 |
|
|
the library.
|
| 4188 |
|
|
</blockquote>
|
| 4189 |
|
|
|
| 4190 |
|
|
<p>In the front matter of class 22, locales, add:</p>
|
| 4191 |
|
|
<blockquote>
|
| 4192 |
|
|
Template parameter types internT and externT shall meet the
|
| 4193 |
|
|
requirements of charT (described in 21 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.strings"> [lib.strings]</a>).
|
| 4194 |
|
|
</blockquote>
|
| 4195 |
|
|
<p><b>Rationale:</b></p>
|
| 4196 |
|
|
<p>
|
| 4197 |
|
|
Again, a blanket clause isn't blanket enough. Also, we've got a
|
| 4198 |
|
|
couple of names that we don't have blanket requirement statements
|
| 4199 |
|
|
for. The only issue is what to do about stateT. This wording is
|
| 4200 |
|
|
thin, but probably adequate.</p>
|
| 4201 |
|
|
<hr>
|
| 4202 |
|
|
<a name="497"><h3>497. meaning of numeric_limits::traps for floating point types</h3></a><p><b>Section:</b> 18.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.numeric.limits.members"> [lib.numeric.limits.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 2 Mar 2005</p>
|
| 4203 |
|
|
|
| 4204 |
|
|
<p>18.2.1.2, p59 says this much about the traps member of numeric_limits:</p>
|
| 4205 |
|
|
|
| 4206 |
|
|
<blockquote>
|
| 4207 |
|
|
<p>static const bool traps;<br>
|
| 4208 |
|
|
-59- true if trapping is implemented for the type.204)
|
| 4209 |
|
|
<br>
|
| 4210 |
|
|
Footnote 204: Required by LIA-1.
|
| 4211 |
|
|
</p>
|
| 4212 |
|
|
</blockquote>
|
| 4213 |
|
|
|
| 4214 |
|
|
<p>It's not clear what is meant by "is implemented" here.</p>
|
| 4215 |
|
|
|
| 4216 |
|
|
<p>
|
| 4217 |
|
|
In the context of floating point numbers it seems reasonable to expect
|
| 4218 |
|
|
to be able to use traps to determine whether a program can "safely" use
|
| 4219 |
|
|
infinity(), quiet_NaN(), etc., in arithmetic expressions, that is
|
| 4220 |
|
|
without causing a trap (i.e., on UNIX without having to worry about
|
| 4221 |
|
|
getting a signal). When traps is true, I would expect any of the
|
| 4222 |
|
|
operations in section 7 of IEEE 754 to cause a trap (and my program
|
| 4223 |
|
|
to get a SIGFPE). So, for example, on Alpha, I would expect traps
|
| 4224 |
|
|
to be true by default (unless I compiled my program with the -ieee
|
| 4225 |
|
|
option), false by default on most other popular architectures,
|
| 4226 |
|
|
including IA64, MIPS, PA-RISC, PPC, SPARC, and x86 which require
|
| 4227 |
|
|
traps to be explicitly enabled by the program.
|
| 4228 |
|
|
</p>
|
| 4229 |
|
|
|
| 4230 |
|
|
<p>
|
| 4231 |
|
|
Another possible interpretation of p59 is that traps should be true
|
| 4232 |
|
|
on any implementation that supports traps regardless of whether they
|
| 4233 |
|
|
are enabled by default or not. I don't think such an interpretation
|
| 4234 |
|
|
makes the traps member very useful, even though that is how traps is
|
| 4235 |
|
|
implemented on several platforms. It is also the only way to implement
|
| 4236 |
|
|
traps on platforms that allow programs to enable and disable trapping
|
| 4237 |
|
|
at runtime.
|
| 4238 |
|
|
</p>
|
| 4239 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4240 |
|
|
<p>Change p59 to read:</p>
|
| 4241 |
|
|
<blockquote>True if, at program startup, there exists a value of the type that
|
| 4242 |
|
|
would cause an arithmetic operation using that value to trap.</blockquote>
|
| 4243 |
|
|
<p><b>Rationale:</b></p>
|
| 4244 |
|
|
<p>
|
| 4245 |
|
|
Real issue, since trapping can be turned on and off. Unclear what a
|
| 4246 |
|
|
static query can say about a dynamic issue. The real advice we should
|
| 4247 |
|
|
give users is to use cfenv for these sorts of queries. But this new
|
| 4248 |
|
|
proposed resolution is at least consistent and slightly better than
|
| 4249 |
|
|
nothing.</p>
|
| 4250 |
|
|
<hr>
|
| 4251 |
|
|
<a name="498"><h3>498. Requirements for partition() and stable_partition() too strong</h3></a><p><b>Section:</b> 25.2.12 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.partitions"> [lib.alg.partitions]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Sean Parent, Joe Gottman <b>Date:</b> 4 May 2005</p>
|
| 4252 |
|
|
<p>
|
| 4253 |
|
|
Problem:
|
| 4254 |
|
|
The iterator requirements for partition() and stable_partition() [25.2.12]
|
| 4255 |
|
|
are listed as BidirectionalIterator, however, there are efficient algorithms
|
| 4256 |
|
|
for these functions that only require ForwardIterator that have been known
|
| 4257 |
|
|
since before the standard existed. The SGI implementation includes these (see
|
| 4258 |
|
|
<a href="http://www.sgi.com/tech/stl/partition.html">http://www.sgi.com/tech/stl/partition.html</a>
|
| 4259 |
|
|
and
|
| 4260 |
|
|
<a href="http://www.sgi.com/tech/stl/stable_partition.html">http://www.sgi.com/tech/stl/stable_partition.html</a>).
|
| 4261 |
|
|
</p>
|
| 4262 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4263 |
|
|
<p>
|
| 4264 |
|
|
Change 25.2.12 from </p>
|
| 4265 |
|
|
<blockquote><pre>template<class BidirectionalIterator, class Predicate>
|
| 4266 |
|
|
BidirectionalIterator partition(BidirectionalIterato r first,
|
| 4267 |
|
|
BidirectionalIterator last,
|
| 4268 |
|
|
Predicate pred);
|
| 4269 |
|
|
</pre></blockquote>
|
| 4270 |
|
|
<p>to </p>
|
| 4271 |
|
|
<blockquote><pre>template<class ForwardIterator, class Predicate>
|
| 4272 |
|
|
ForwardIterator partition(ForwardIterator first,
|
| 4273 |
|
|
ForwardIterator last,
|
| 4274 |
|
|
Predicate pred);
|
| 4275 |
|
|
</pre></blockquote>
|
| 4276 |
|
|
<p>Change the complexity from </p>
|
| 4277 |
|
|
|
| 4278 |
|
|
<blockquote><p>
|
| 4279 |
|
|
At most (last - first)/2 swaps are done. Exactly (last - first)
|
| 4280 |
|
|
applications of the predicate are done.
|
| 4281 |
|
|
</p></blockquote>
|
| 4282 |
|
|
|
| 4283 |
|
|
<p>to </p>
|
| 4284 |
|
|
|
| 4285 |
|
|
<blockquote><p>
|
| 4286 |
|
|
If ForwardIterator is a bidirectional_iterator, at most (last - first)/2
|
| 4287 |
|
|
swaps are done; otherwise at most (last - first) swaps are done. Exactly
|
| 4288 |
|
|
(last - first) applications of the predicate are done.
|
| 4289 |
|
|
</p></blockquote>
|
| 4290 |
|
|
|
| 4291 |
|
|
<p><b>Rationale:</b></p>
|
| 4292 |
|
|
Partition is a "foundation" algorithm useful in many contexts (like sorting
|
| 4293 |
|
|
as just one example) - my motivation for extending it to include forward
|
| 4294 |
|
|
iterators is slist - without this extension you can't partition an slist
|
| 4295 |
|
|
(without writing your own partition). Holes like this in the standard
|
| 4296 |
|
|
library weaken the argument for generic programming (ideally I'd be able
|
| 4297 |
|
|
to provide a library that would refine std::partition() to other concepts
|
| 4298 |
|
|
without fear of conflicting with other libraries doing the same - but
|
| 4299 |
|
|
that is a digression). I consider the fact that partition isn't defined
|
| 4300 |
|
|
to work for ForwardIterator a minor embarrassment.
|
| 4301 |
|
|
|
| 4302 |
|
|
<p><i>[Mont Tremblant: Moved to Open, request motivation and use cases
|
| 4303 |
|
|
by next meeting. Sean provided further rationale by post-meeting
|
| 4304 |
|
|
mailing.]</i></p>
|
| 4305 |
|
|
|
| 4306 |
|
|
<hr>
|
| 4307 |
|
|
<a name="499"><h3>499. Std. doesn't seem to require stable_sort() to be stable!</h3></a><p><b>Section:</b> 25.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.stable.sort"> [lib.stable.sort]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Prateek Karandikar <b>Date:</b> 12 Apr 2005</p>
|
| 4308 |
|
|
<blockquote>
|
| 4309 |
|
|
<p>
|
| 4310 |
|
|
17.3.1.1 Summary</p>
|
| 4311 |
|
|
|
| 4312 |
|
|
<p>
|
| 4313 |
|
|
1 The Summary provides a synopsis of the category, and introduces the
|
| 4314 |
|
|
first-level subclauses. Each subclause also provides a summary, listing
|
| 4315 |
|
|
the headers specified in the subclause and the library entities
|
| 4316 |
|
|
provided in each header.
|
| 4317 |
|
|
</p>
|
| 4318 |
|
|
<p>
|
| 4319 |
|
|
2 Paragraphs labelled "Note(s):" or "Example(s):" are informative,
|
| 4320 |
|
|
other paragraphs are normative.
|
| 4321 |
|
|
</p>
|
| 4322 |
|
|
</blockquote>
|
| 4323 |
|
|
|
| 4324 |
|
|
<p>So this means that a "Notes" paragraph wouldn't be normative. </p>
|
| 4325 |
|
|
|
| 4326 |
|
|
<blockquote>
|
| 4327 |
|
|
<p>
|
| 4328 |
|
|
25.3.1.2 stable_sort
|
| 4329 |
|
|
</p>
|
| 4330 |
|
|
<pre>template<class RandomAccessIterator>
|
| 4331 |
|
|
void stable_sort(RandomAccessIterat or first, RandomAccessIterator last);
|
| 4332 |
|
|
|
| 4333 |
|
|
template<class RandomAccessIterator, class Compare>
|
| 4334 |
|
|
void stable_sort(RandomAccessIterat or first, RandomAccessIterator last, Compare comp);
|
| 4335 |
|
|
</pre>
|
| 4336 |
|
|
<p>
|
| 4337 |
|
|
1 Effects: Sorts the elements in the range [first, last).
|
| 4338 |
|
|
</p>
|
| 4339 |
|
|
<p>
|
| 4340 |
|
|
2 Complexity: It does at most N(log N)^2 (where N == last - first)
|
| 4341 |
|
|
comparisons; if enough extra memory is available, it is N log N.
|
| 4342 |
|
|
</p>
|
| 4343 |
|
|
<p>
|
| 4344 |
|
|
3 Notes: Stable: the relative order of the equivalent elements is
|
| 4345 |
|
|
preserved.
|
| 4346 |
|
|
</p>
|
| 4347 |
|
|
</blockquote>
|
| 4348 |
|
|
|
| 4349 |
|
|
<p>
|
| 4350 |
|
|
The Notes para is informative, and nowhere else is stability mentioned above.
|
| 4351 |
|
|
</p>
|
| 4352 |
|
|
|
| 4353 |
|
|
<p>
|
| 4354 |
|
|
Also, I just searched for the word "stable" in my copy of the Standard.
|
| 4355 |
|
|
and the phrase "Notes: Stable: the relative order of the elements..."
|
| 4356 |
|
|
is repeated several times in the Standard library clauses for
|
| 4357 |
|
|
describing various functions. How is it that stability is talked about
|
| 4358 |
|
|
in the informative paragraph? Or am I missing something obvious?
|
| 4359 |
|
|
</p>
|
| 4360 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4361 |
|
|
<p>
|
| 4362 |
|
|
</p>
|
| 4363 |
|
|
<hr>
|
| 4364 |
|
|
<a name="501"><h3>501. Proposal: strengthen guarantees of lib.comparisons</h3></a><p><b>Section:</b> 20.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.comparisons"> [lib.comparisons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Me <anti_spam_email2003@yahoo.com> <b>Date:</b> 7 Jun 2005</p>
|
| 4365 |
|
|
<blockquote>
|
| 4366 |
|
|
"For templates greater, less, greater_equal, and less_equal,
|
| 4367 |
|
|
the specializations for any pointer type yield a total order, even if
|
| 4368 |
|
|
the built-in operators <, >, <=, >= do not."
|
| 4369 |
|
|
</blockquote>
|
| 4370 |
|
|
|
| 4371 |
|
|
<p>
|
| 4372 |
|
|
The standard should do much better than guarantee that these provide a
|
| 4373 |
|
|
total order, it should guarantee that it can be used to test if memory
|
| 4374 |
|
|
overlaps, i.e. write a portable memmove. You can imagine a platform
|
| 4375 |
|
|
where the built-in operators use a uint32_t comparison (this tests for
|
| 4376 |
|
|
overlap on this platform) but the less<T*> functor is allowed to be
|
| 4377 |
|
|
defined to use a int32_t comparison. On this platform, if you use
|
| 4378 |
|
|
std::less with the intent of making a portable memmove, comparison on
|
| 4379 |
|
|
an array that straddles the 0x7FFFFFFF/0x8000000 boundary can give
|
| 4380 |
|
|
incorrect results.
|
| 4381 |
|
|
</p>
|
| 4382 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4383 |
|
|
<p>
|
| 4384 |
|
|
Add a footnote to 20.3.3/8 saying:
|
| 4385 |
|
|
</p>
|
| 4386 |
|
|
|
| 4387 |
|
|
<blockquote>
|
| 4388 |
|
|
Given a p1 and p2 such that p1 points to N objects of type T and p2
|
| 4389 |
|
|
points to M objects of type T. If [p1,p1+N) does not overlap [p2,p2+M),
|
| 4390 |
|
|
less returns the same value when comparing all pointers in [p1,p1+N) to
|
| 4391 |
|
|
all pointers in [p2,p2+M). Otherwise, there is a value Q and a value R
|
| 4392 |
|
|
such that less returns the same value when comparing all pointers in
|
| 4393 |
|
|
[p1,p1+Q) to all pointers in [p2,p2+R) and an opposite value when
|
| 4394 |
|
|
comparing all pointers in [p1+Q,p1+N) to all pointers in [p2+R,p2+M).
|
| 4395 |
|
|
For the sake of completeness, the null pointer value (4.10) for T is
|
| 4396 |
|
|
considered to be an array of 1 object that doesn't overlap with any
|
| 4397 |
|
|
non-null pointer to T. less_equal, greater, greater_equal, equal_to,
|
| 4398 |
|
|
and not_equal_to give the expected results based on the total ordering
|
| 4399 |
|
|
semantics of less. For T of void, treat it as having similar semantics
|
| 4400 |
|
|
as T of char i.e. less<cv T*>(a, b) gives the same results as less<cv
|
| 4401 |
|
|
void*>(a, b) which gives the same results as less<cv char*>((cv
|
| 4402 |
|
|
char*)(cv void*)a, (cv char*)(cv void*)b).
|
| 4403 |
|
|
</blockquote>
|
| 4404 |
|
|
|
| 4405 |
|
|
<p>
|
| 4406 |
|
|
I'm also thinking there should be a footnote to 20.3.3/1 saying that if
|
| 4407 |
|
|
A and B are similar types (4.4/4), comp<A>(a,b) returns the same value
|
| 4408 |
|
|
as comp<B>(a,b) (where comp is less, less_equal, etc.). But this might
|
| 4409 |
|
|
be problematic if there is some really funky operator overloading going
|
| 4410 |
|
|
on that does different things based on cv (that should be undefined
|
| 4411 |
|
|
behavior if somebody does that though). This at least should be
|
| 4412 |
|
|
guaranteed for all POD types (especially pointers) that use the
|
| 4413 |
|
|
built-in comparison operators.
|
| 4414 |
|
|
</p>
|
| 4415 |
|
|
|
| 4416 |
|
|
<hr>
|
| 4417 |
|
|
<a name="502"><h3>502. Proposition: Clarification of the interaction between a facet and an iterator</h3></a><p><b>Section:</b> 22.1.1.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.category"> [lib.locale.category]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Christopher Conrade Zseleghovski <b>Date:</b> 7 Jun 2005</p>
|
| 4418 |
|
|
<p>
|
| 4419 |
|
|
Motivation:
|
| 4420 |
|
|
</p>
|
| 4421 |
|
|
|
| 4422 |
|
|
<p>
|
| 4423 |
|
|
This requirement seems obvious to me, it is the essence of code modularity.
|
| 4424 |
|
|
I have complained to Mr. Plauger that the Dinkumware library does not
|
| 4425 |
|
|
observe this principle but he objected that this behaviour is not covered in
|
| 4426 |
|
|
the standard.
|
| 4427 |
|
|
</p>
|
| 4428 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4429 |
|
|
<p>
|
| 4430 |
|
|
Append the following point to 22.1.1.1.1:
|
| 4431 |
|
|
</p>
|
| 4432 |
|
|
|
| 4433 |
|
|
<p>
|
| 4434 |
|
|
6. The implementation of a facet of Table 52 parametrized with an
|
| 4435 |
|
|
InputIterator/OutputIterator should use that iterator only as character
|
| 4436 |
|
|
source/sink respectively.
|
| 4437 |
|
|
For a *_get facet, it means that the value received depends only on the
|
| 4438 |
|
|
sequence of input characters and not on how they are accessed.
|
| 4439 |
|
|
For a *_put facet, it means that the sequence of characters output depends
|
| 4440 |
|
|
only on the value to be formatted and not of how the characters are stored.
|
| 4441 |
|
|
</p>
|
| 4442 |
|
|
<hr>
|
| 4443 |
|
|
<a name="503"><h3>503. more on locales</h3></a><p><b>Section:</b> 22.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.categories"> [lib.locale.categories]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> P.J. Plauger <b>Date:</b> 20 Jun 2005</p>
|
| 4444 |
|
|
<p>
|
| 4445 |
|
|
a) In 22.2.1.1 para. 2 we refer to "the instantiations required in Table
|
| 4446 |
|
|
51" to refer to the facet *objects* associated with a locale. And we
|
| 4447 |
|
|
almost certainly mean just those associated with the default or "C"
|
| 4448 |
|
|
locale. Otherwise, you can't switch to a locale that enforces a different
|
| 4449 |
|
|
mapping between narrow and wide characters, or that defines additional
|
| 4450 |
|
|
uppercase characters.
|
| 4451 |
|
|
</p>
|
| 4452 |
|
|
|
| 4453 |
|
|
<p>
|
| 4454 |
|
|
b) 22.2.1.5 para. 3 (codecvt) has the same issues.
|
| 4455 |
|
|
</p>
|
| 4456 |
|
|
|
| 4457 |
|
|
<p>
|
| 4458 |
|
|
c) 22.2.1.5.2 (do_unshift) is even worse. It *forbids* the generation of
|
| 4459 |
|
|
a homing sequence for the basic character set, which might very well need
|
| 4460 |
|
|
one.
|
| 4461 |
|
|
</p>
|
| 4462 |
|
|
|
| 4463 |
|
|
<p>
|
| 4464 |
|
|
d) 22.2.1.5.2 (do_length) likewise dictates that the default mapping
|
| 4465 |
|
|
between wide and narrow characters be taken as one-for-one.
|
| 4466 |
|
|
</p>
|
| 4467 |
|
|
|
| 4468 |
|
|
<p>
|
| 4469 |
|
|
e) 22.2.2 para. 2 (num_get/put) is both muddled and vacuous, as far as
|
| 4470 |
|
|
I can tell. The muddle is, as before, calling Table 51 a list of
|
| 4471 |
|
|
instantiations. But the constraint it applies seems to me to cover
|
| 4472 |
|
|
*all* defined uses of num_get/put, so why bother to say so?
|
| 4473 |
|
|
</p>
|
| 4474 |
|
|
|
| 4475 |
|
|
<p>
|
| 4476 |
|
|
f) 22.2.3.1.2 para. 1(do_decimal_point) says "The required instantiations
|
| 4477 |
|
|
return '.' or L'.'.) Presumably this means "as appropriate for the
|
| 4478 |
|
|
character type. But given the vague definition of "required" earlier,
|
| 4479 |
|
|
this overrules *any* change of decimal point for non "C" locales.
|
| 4480 |
|
|
Surely we don't want to do that.
|
| 4481 |
|
|
</p>
|
| 4482 |
|
|
|
| 4483 |
|
|
<p>
|
| 4484 |
|
|
g) 22.2.3.1.2 para. 2 (do_thousands_sep) says "The required instantiations
|
| 4485 |
|
|
return ',' or L','.) As above, this probably means "as appropriate for the
|
| 4486 |
|
|
character type. But this overrules the "C" locale, which requires *no*
|
| 4487 |
|
|
character ('\0') for the thousands separator. Even if we agree that we
|
| 4488 |
|
|
don't mean to block changes in decimal point or thousands separator,
|
| 4489 |
|
|
we should also eliminate this clear incompatibility with C.
|
| 4490 |
|
|
</p>
|
| 4491 |
|
|
|
| 4492 |
|
|
<p>
|
| 4493 |
|
|
h) 22.2.3.1.2 para. 2 (do_grouping) says "The required instantiations
|
| 4494 |
|
|
return the empty string, indicating no grouping." Same considerations
|
| 4495 |
|
|
as for do_decimal_point.
|
| 4496 |
|
|
</p>
|
| 4497 |
|
|
|
| 4498 |
|
|
<p>
|
| 4499 |
|
|
i) 22.2.4.1 para. 1 (collate) refers to "instantiations required in Table
|
| 4500 |
|
|
51". Same bad jargon.
|
| 4501 |
|
|
</p>
|
| 4502 |
|
|
|
| 4503 |
|
|
<p>
|
| 4504 |
|
|
j) 22.2.4.1.2 para. 1 (do_compare) refers to "instantiations required
|
| 4505 |
|
|
in Table 51". Same bad jargon.
|
| 4506 |
|
|
</p>
|
| 4507 |
|
|
|
| 4508 |
|
|
<p>
|
| 4509 |
|
|
k) 22.2.5 para. 1 (time_get/put) uses the same muddled and vacuous
|
| 4510 |
|
|
as num_get/put.
|
| 4511 |
|
|
</p>
|
| 4512 |
|
|
|
| 4513 |
|
|
<p>
|
| 4514 |
|
|
l) 22.2.6 para. 2 (money_get/put) uses the same muddled and vacuous
|
| 4515 |
|
|
as num_get/put.
|
| 4516 |
|
|
</p>
|
| 4517 |
|
|
|
| 4518 |
|
|
<p>
|
| 4519 |
|
|
m) 22.2.6.3.2 (do_pos/neg_format) says "The instantiations required
|
| 4520 |
|
|
in Table 51 ... return an object of type pattern initialized to
|
| 4521 |
|
|
{symbol, sign, none, value}." This once again *overrides* the "C"
|
| 4522 |
|
|
locale, as well as any other locale."
|
| 4523 |
|
|
</p>
|
| 4524 |
|
|
|
| 4525 |
|
|
<p>
|
| 4526 |
|
|
3) We constrain the use_facet calls that can be made by num_get/put,
|
| 4527 |
|
|
so why don't we do the same for money_get/put? Or for any of the
|
| 4528 |
|
|
other facets, for that matter?
|
| 4529 |
|
|
</p>
|
| 4530 |
|
|
|
| 4531 |
|
|
<p>
|
| 4532 |
|
|
4) As an almost aside, we spell out when a facet needs to use the ctype
|
| 4533 |
|
|
facet, but several also need to use a codecvt facet and we don't say so.
|
| 4534 |
|
|
</p>
|
| 4535 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4536 |
|
|
<p>
|
| 4537 |
|
|
</p>
|
| 4538 |
|
|
<hr>
|
| 4539 |
|
|
<a name="504"><h3>504. Integer types in pseudo-random number engine requirements</h3></a><p><b>Section:</b> TR1 5.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.req"> [tr.rand.req]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4540 |
|
|
<p>
|
| 4541 |
|
|
In [tr.rand.req], Paragraph 2 states that "... s is a value of integral type,
|
| 4542 |
|
|
g is an ... object returning values of unsigned integral type ..."
|
| 4543 |
|
|
</p>
|
| 4544 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4545 |
|
|
<p>
|
| 4546 |
|
|
In 5.1.1 [tr.rand.req], Paragraph 2 replace
|
| 4547 |
|
|
</p>
|
| 4548 |
|
|
|
| 4549 |
|
|
<blockquote>
|
| 4550 |
|
|
... s is a value of integral type, g is an lvalue of a type other than X that
|
| 4551 |
|
|
defines a zero-argument function object returning values of <del>unsigned integral</del> type
|
| 4552 |
|
|
<ins><tt>unsigned long int</tt></ins>,
|
| 4553 |
|
|
...
|
| 4554 |
|
|
</blockquote>
|
| 4555 |
|
|
|
| 4556 |
|
|
<p>
|
| 4557 |
|
|
In 5.1.1 [tr.rand.seq], Table 16, replace in the line for X(s)
|
| 4558 |
|
|
</p>
|
| 4559 |
|
|
|
| 4560 |
|
|
<blockquote>
|
| 4561 |
|
|
creates an engine with the initial internal state
|
| 4562 |
|
|
determined by <ins><tt>static_cast<unsigned long>(</tt></ins><tt><i>s</i></tt><ins><tt>)</tt></ins>
|
| 4563 |
|
|
</blockquote>
|
| 4564 |
|
|
|
| 4565 |
|
|
<p><i>[
|
| 4566 |
|
|
Mont Tremblant: Both s and g should be unsigned long.
|
| 4567 |
|
|
This should refer to the constructor signatures. Jens provided wording post Mont Tremblant.
|
| 4568 |
|
|
]</i></p>
|
| 4569 |
|
|
|
| 4570 |
|
|
<p><b>Rationale:</b></p>
|
| 4571 |
|
|
<p>
|
| 4572 |
|
|
Jens: Just requiring X(unsigned long) still makes it possible
|
| 4573 |
|
|
for an evil library writer to also supply a X(int) that does something
|
| 4574 |
|
|
unexpected. The wording above requires that X(s) always performs
|
| 4575 |
|
|
as if X(unsigned long) would have been called. I believe that is
|
| 4576 |
|
|
sufficient and implements our intentions from Mont Tremblant. I
|
| 4577 |
|
|
see no additional use in actually requiring a X(unsigned long)
|
| 4578 |
|
|
signature. u.seed(s) is covered by its reference to X(s), same
|
| 4579 |
|
|
arguments.
|
| 4580 |
|
|
</p>
|
| 4581 |
|
|
<hr>
|
| 4582 |
|
|
<a name="505"><h3>505. Result_type in random distribution requirements</h3></a><p><b>Section:</b> TR1 5.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.req"> [tr.rand.req]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4583 |
|
|
<p>
|
| 4584 |
|
|
Table 17: Random distribution requirements
|
| 4585 |
|
|
</p>
|
| 4586 |
|
|
<p>
|
| 4587 |
|
|
Row 1 requires that each random distribution provide a nested type "input_type";
|
| 4588 |
|
|
this type denotes the type of the values that the distribution consumes.
|
| 4589 |
|
|
</p>
|
| 4590 |
|
|
<p>
|
| 4591 |
|
|
Inspection of all distributions in [tr.rand.dist] reveals that each distribution
|
| 4592 |
|
|
provides a second typedef ("result_type") that denotes the type of the values the
|
| 4593 |
|
|
distribution produces when called.
|
| 4594 |
|
|
</p>
|
| 4595 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4596 |
|
|
<p>
|
| 4597 |
|
|
It seems to me that this is also a requirement
|
| 4598 |
|
|
for all distributions and should therefore be indicated as such via a new second
|
| 4599 |
|
|
row to this table 17:
|
| 4600 |
|
|
</p>
|
| 4601 |
|
|
<table border="1" cellpadding="5">
|
| 4602 |
|
|
<tbody><tr>
|
| 4603 |
|
|
<td>X::result_type</td>
|
| 4604 |
|
|
<td>T</td>
|
| 4605 |
|
|
<td>---</td>
|
| 4606 |
|
|
<td>compile-time</td>
|
| 4607 |
|
|
</tr>
|
| 4608 |
|
|
</tbody></table>
|
| 4609 |
|
|
<hr>
|
| 4610 |
|
|
<a name="506"><h3>506. Requirements of Distribution parameter for variate_generator</h3></a><p><b>Section:</b> TR1 5.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.var"> [tr.rand.var]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4611 |
|
|
<p>
|
| 4612 |
|
|
Paragraph 3 requires that template argument U (which corresponds to template
|
| 4613 |
|
|
parameter Engine) satisfy all uniform random number generator requirements.
|
| 4614 |
|
|
However, there is no analogous requirement regarding the template argument
|
| 4615 |
|
|
that corresponds to template parameter Distribution. We believe there should
|
| 4616 |
|
|
be, and that it should require that this template argument satisfy all random
|
| 4617 |
|
|
distribution requirements.
|
| 4618 |
|
|
</p>
|
| 4619 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4620 |
|
|
<p>
|
| 4621 |
|
|
Consequence 1: Remove the precondition clauses [tr.rand.var]/16 and /18.
|
| 4622 |
|
|
</p>
|
| 4623 |
|
|
<p>
|
| 4624 |
|
|
Consequence 2: Add max() and min() functions to those distributions that
|
| 4625 |
|
|
do not already have them.
|
| 4626 |
|
|
</p>
|
| 4627 |
|
|
|
| 4628 |
|
|
<p><i>[
|
| 4629 |
|
|
Mont Tremblant: Jens reccommends NAD, min/max not needed everywhere.
|
| 4630 |
|
|
Marc supports having min and max to satisfy generic programming interface.
|
| 4631 |
|
|
]</i></p>
|
| 4632 |
|
|
|
| 4633 |
|
|
<hr>
|
| 4634 |
|
|
<a name="507"><h3>507. Missing requirement for variate_generator::operator()</h3></a><p><b>Section:</b> TR1 5.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.var"> [tr.rand.var]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4635 |
|
|
<p>
|
| 4636 |
|
|
Paragraph 11 of [tr.rand.var] equires that the member template
|
| 4637 |
|
|
</p>
|
| 4638 |
|
|
<blockquote><pre>template<class T> result_type operator() (T value);
|
| 4639 |
|
|
</pre></blockquote>
|
| 4640 |
|
|
<p>
|
| 4641 |
|
|
return
|
| 4642 |
|
|
</p>
|
| 4643 |
|
|
<blockquote><pre>distribution()(e, value)
|
| 4644 |
|
|
</pre></blockquote>
|
| 4645 |
|
|
<p>
|
| 4646 |
|
|
However, not all distributions have an operator() with a corresponding signature.
|
| 4647 |
|
|
</p>
|
| 4648 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4649 |
|
|
<p>
|
| 4650 |
|
|
We therefore recommend that we insert the following precondition before paragraph 11:
|
| 4651 |
|
|
</p>
|
| 4652 |
|
|
<blockquote>
|
| 4653 |
|
|
Precondition: <tt>distribution().operator()(e,value)</tt> is well-formed.
|
| 4654 |
|
|
</blockquote>
|
| 4655 |
|
|
<hr>
|
| 4656 |
|
|
<a name="508"><h3>508. Bad parameters for ranlux64_base_01</h3></a><p><b>Section:</b> TR1 5.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.predef"> [tr.rand.predef]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4657 |
|
|
<p>
|
| 4658 |
|
|
The fifth of these engines with predefined parameters, ranlux64_base_01,
|
| 4659 |
|
|
appears to have an unintentional error for which there is a simple correction.
|
| 4660 |
|
|
The two pre-defined subtract_with_carry_01 engines are given as:
|
| 4661 |
|
|
</p>
|
| 4662 |
|
|
<blockquote><pre>typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01;
|
| 4663 |
|
|
typedef subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01;
|
| 4664 |
|
|
</pre></blockquote>
|
| 4665 |
|
|
<p>
|
| 4666 |
|
|
We demonstrate below that ranlux64_base_01 fails to meet the intent of the
|
| 4667 |
|
|
random number generation proposal, but that the simple correction to
|
| 4668 |
|
|
</p>
|
| 4669 |
|
|
<blockquote><pre>typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
|
| 4670 |
|
|
</pre></blockquote>
|
| 4671 |
|
|
<p>
|
| 4672 |
|
|
does meet the intent of defining well-known good parameterizations.
|
| 4673 |
|
|
</p>
|
| 4674 |
|
|
<p>
|
| 4675 |
|
|
The ranlux64_base_01 engine as presented fails to meet the intent for
|
| 4676 |
|
|
predefined engines, stated in proposal N1398 (section E):
|
| 4677 |
|
|
</p>
|
| 4678 |
|
|
<blockquote><p>
|
| 4679 |
|
|
In order to make good random numbers available to a large number of library
|
| 4680 |
|
|
users, this proposal not only defines generic random-number engines, but also
|
| 4681 |
|
|
provides a number of predefined well-known good parameterizations for those.
|
| 4682 |
|
|
</p></blockquote>
|
| 4683 |
|
|
<p>
|
| 4684 |
|
|
The predefined ranlux_base_01 engine has been proven [1,2,3] to have a very
|
| 4685 |
|
|
long period and so meets this criterion. This property makes it suitable for
|
| 4686 |
|
|
use in the excellent discard_block engines defined subsequently. The proof
|
| 4687 |
|
|
of long period relies on the fact (proven in [1]) that 2**(w*r) - 2**(w*s)
|
| 4688 |
|
|
+ 1 is prime (w, r, and s are template parameters to subtract_with_carry_01,
|
| 4689 |
|
|
as defined in [tr.rand.eng.sub1]).
|
| 4690 |
|
|
</p>
|
| 4691 |
|
|
<p>
|
| 4692 |
|
|
The ranlux64_base_01 engine as presented in [tr.rand.predef] uses w=48, r=24, s=10.
|
| 4693 |
|
|
For these numbers, the combination 2**(w*r)-2**(w*s)+1 is non-prime (though
|
| 4694 |
|
|
explicit factorization would be a challenge). In consequence, while it is
|
| 4695 |
|
|
certainly possible for some seeding states that this engine would have a very
|
| 4696 |
|
|
long period, it is not at all Òwell-knownÓ that this is the case. The intent
|
| 4697 |
|
|
in the N1398 proposal involved the base of the ranlux64 engine, which finds heavy
|
| 4698 |
|
|
use in the physics community. This is isomorphic to the predefined ranlux_base_01,
|
| 4699 |
|
|
but exploits the ability of double variables to hold (at least) 48 bits of mantissa,
|
| 4700 |
|
|
to deliver 48 random bits at a time rather than 24.
|
| 4701 |
|
|
</p>
|
| 4702 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4703 |
|
|
<p>
|
| 4704 |
|
|
To achieve this intended behavior, the correct template parameteriztion would be:
|
| 4705 |
|
|
</p>
|
| 4706 |
|
|
<blockquote><pre>typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
|
| 4707 |
|
|
</pre></blockquote>
|
| 4708 |
|
|
<p>
|
| 4709 |
|
|
The sequence of mantissa bits delivered by this is isomorphic (treating each
|
| 4710 |
|
|
double as having the bits of two floats) to that delivered by ranlux_base_01.
|
| 4711 |
|
|
</p>
|
| 4712 |
|
|
<p>
|
| 4713 |
|
|
<b>References:</b>
|
| 4714 |
|
|
</p>
|
| 4715 |
|
|
<ol>
|
| 4716 |
|
|
<li>F. James, Comput. Phys. Commun. 60(1990) 329</li>
|
| 4717 |
|
|
<li>G. Marsaglia and A. Zaman, Ann. Appl. Prob 1(1991) 462</li>
|
| 4718 |
|
|
<li>M. Luscher, Comput. Phys. Commun. 79(1994) 100-110</li>
|
| 4719 |
|
|
</ol>
|
| 4720 |
|
|
|
| 4721 |
|
|
<hr>
|
| 4722 |
|
|
<a name="509"><h3>509. Uniform_int template parameters</h3></a><p><b>Section:</b> TR1 5.1.7.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.dist.iunif"> [tr.rand.dist.iunif]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4723 |
|
|
<p>
|
| 4724 |
|
|
In [tr.rand.dist.iunif] the uniform_int distribution currently has a single
|
| 4725 |
|
|
template parameter, IntType, used as the input_type and as the result_type
|
| 4726 |
|
|
of the distribution. We believe there is no reason to conflate these types
|
| 4727 |
|
|
in this way.
|
| 4728 |
|
|
</p>
|
| 4729 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4730 |
|
|
<p>
|
| 4731 |
|
|
We recommend that there be a second template parameter to
|
| 4732 |
|
|
reflect the distributionÕs input_type, and that the existing first template
|
| 4733 |
|
|
parameter continue to reflect (solely) the result_type:
|
| 4734 |
|
|
</p>
|
| 4735 |
|
|
<blockquote><pre>template< class IntType = int, UIntType = unsigned int >
|
| 4736 |
|
|
class uniform_int
|
| 4737 |
|
|
{
|
| 4738 |
|
|
public:
|
| 4739 |
|
|
// types
|
| 4740 |
|
|
typedef UIntType input_type;
|
| 4741 |
|
|
typedef IntType result_type;
|
| 4742 |
|
|
</pre></blockquote>
|
| 4743 |
|
|
<hr>
|
| 4744 |
|
|
<a name="510"><h3>510. Input_type for bernoulli_distribution</h3></a><p><b>Section:</b> TR1 5.1.7.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.dist.bern"> [tr.rand.dist.bern]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4745 |
|
|
<p>
|
| 4746 |
|
|
In [tr.rand.dist.bern] the distribution currently requires;
|
| 4747 |
|
|
</p>
|
| 4748 |
|
|
<blockquote><pre>typedef int input_type;
|
| 4749 |
|
|
</pre></blockquote>
|
| 4750 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4751 |
|
|
<p>
|
| 4752 |
|
|
We believe this is an unfortunate choice, and recommend instead:
|
| 4753 |
|
|
</p>
|
| 4754 |
|
|
<blockquote><pre>typedef unsigned int input_type;
|
| 4755 |
|
|
</pre></blockquote>
|
| 4756 |
|
|
<hr>
|
| 4757 |
|
|
<a name="511"><h3>511. Input_type for binomial_distribution</h3></a><p><b>Section:</b> TR1 5.1.7.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.dist.bin"> [tr.rand.dist.bin]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4758 |
|
|
<p>
|
| 4759 |
|
|
Unlike all other distributions in TR1, this binomial_distribution has an
|
| 4760 |
|
|
implementation-defined input_type. We believe this is an unfortunate choice,
|
| 4761 |
|
|
because it hinders users from writing portable code. It also hinders the
|
| 4762 |
|
|
writing of compliance tests. We recommend instead:
|
| 4763 |
|
|
</p>
|
| 4764 |
|
|
<blockquote><pre>typedef RealType input_type;
|
| 4765 |
|
|
</pre></blockquote>
|
| 4766 |
|
|
<p>
|
| 4767 |
|
|
While this choice is somewhat arbitrary (as it was for some of the other
|
| 4768 |
|
|
distributions), we make this particular choice because (unlike all other
|
| 4769 |
|
|
distributions) otherwise this template would not publish its RealType
|
| 4770 |
|
|
argument and so users could not write generic code that accessed this
|
| 4771 |
|
|
second template parameter. In this respect, the choice is consistent with
|
| 4772 |
|
|
the other distributions in TR1.
|
| 4773 |
|
|
</p>
|
| 4774 |
|
|
<p>
|
| 4775 |
|
|
We have two reasons for recommending that a real type be specified instead.
|
| 4776 |
|
|
One reason is based specifically on characteristics of binomial distribution
|
| 4777 |
|
|
implementations, while the other is based on mathematical characteristics of
|
| 4778 |
|
|
probability distribution functions in general.
|
| 4779 |
|
|
</p>
|
| 4780 |
|
|
<p>
|
| 4781 |
|
|
Implementations of binomial distributions commonly use Stirling approximations
|
| 4782 |
|
|
for values in certain ranges. It is far more natural to use real values to
|
| 4783 |
|
|
represent these approximations than it would be to use integral values to do
|
| 4784 |
|
|
so. In other ranges, implementations reply on the Bernoulli distribution to
|
| 4785 |
|
|
obtain values. While TR1Õs bernoulli_distribution::input_type is specified as
|
| 4786 |
|
|
int, we believe this would be better specified as double.
|
| 4787 |
|
|
</p>
|
| 4788 |
|
|
<p>
|
| 4789 |
|
|
This brings us to our main point: The notion of a random distribution rests
|
| 4790 |
|
|
on the notion of a cumulative distribution function, which in turn mathematically
|
| 4791 |
|
|
depends on a continuous dependent variable. Indeed, such a distribution function
|
| 4792 |
|
|
would be meaningless if it depended on discrete values such as integersÑand this
|
| 4793 |
|
|
remains true even if the distribution function were to take discrete steps.
|
| 4794 |
|
|
</p>
|
| 4795 |
|
|
<p>
|
| 4796 |
|
|
Although this note is specifically about binomial_distribution::input_type,
|
| 4797 |
|
|
we intend to recommend that all of the random distributionsÕ input_types be
|
| 4798 |
|
|
specified as a real type (either a RealType template parameter, or double,
|
| 4799 |
|
|
as appropriate).
|
| 4800 |
|
|
</p>
|
| 4801 |
|
|
<p>
|
| 4802 |
|
|
Of the nine distributions in TR1, four already have this characteristic
|
| 4803 |
|
|
(uniform_real, exponential_distribution, normal_distribution, and
|
| 4804 |
|
|
gamma_distribution). We have already argued the case for the binomial the
|
| 4805 |
|
|
remaining four distributions.
|
| 4806 |
|
|
</p>
|
| 4807 |
|
|
<p>
|
| 4808 |
|
|
In the case of uniform_int, we believe that the calculations to produce an
|
| 4809 |
|
|
integer result in a specified range from an integer in a different specified
|
| 4810 |
|
|
range is best done using real arithmetic. This is because it involves a
|
| 4811 |
|
|
product, one of whose terms is the ratio of the extents of the two ranges.
|
| 4812 |
|
|
Without real arithmetic, the results become less uniform: some numbers become
|
| 4813 |
|
|
more (or less) probable that they should be. This is, of course, undesireable
|
| 4814 |
|
|
behavior in a uniform distribution.
|
| 4815 |
|
|
</p>
|
| 4816 |
|
|
<p>
|
| 4817 |
|
|
Finally, we believe that in the case of the bernoulli_distribution (briefly
|
| 4818 |
|
|
mentioned earlier), as well as the cases of the geometric_distribution and the
|
| 4819 |
|
|
poisson_distribution, it would be far more natural to have a real input_type.
|
| 4820 |
|
|
This is because the most natural computation involves the random number
|
| 4821 |
|
|
delivered and the distributionÕs parameter p (in the case of bernoulli_distribution,
|
| 4822 |
|
|
for example, the computation is a comparison against p), and p is already specified
|
| 4823 |
|
|
in each case as having some real type.
|
| 4824 |
|
|
</p>
|
| 4825 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4826 |
|
|
<blockquote><pre>typedef RealType input_type;
|
| 4827 |
|
|
</pre></blockquote>
|
| 4828 |
|
|
<hr>
|
| 4829 |
|
|
<a name="512"></a><h3><a name="512">512. Seeding subtract_with_carry_01 from a single unsigned long</a></h3><p><b>Section:</b> TR1 5.1.4.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.eng.sub1"> [tr.rand.eng.sub1]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4830 |
|
|
<p>
|
| 4831 |
|
|
Paragraph 8 specifies the algorithm by which a subtract_with_carry_01 engine
|
| 4832 |
|
|
is to be seeded given a single unsigned long. This algorithm is seriously
|
| 4833 |
|
|
flawed in the case where the engine parameter w (also known as word_size)
|
| 4834 |
|
|
exceeds 31 [bits]. The key part of the paragraph reads:
|
| 4835 |
|
|
</p>
|
| 4836 |
|
|
<blockquote>
|
| 4837 |
|
|
sets x(-r) ... x(-1) to (lcg(1)*2**(-w)) mod 1
|
| 4838 |
|
|
</blockquote>
|
| 4839 |
|
|
<p>
|
| 4840 |
|
|
and so forth.
|
| 4841 |
|
|
</p>
|
| 4842 |
|
|
<p>
|
| 4843 |
|
|
Since the specified linear congruential engine, lcg, delivers numbers with
|
| 4844 |
|
|
a maximum of 2147483563 (just a shade under 31 bits), then when w is, for
|
| 4845 |
|
|
example, 48, each of the x(i) will be less than 2**-17. The consequence
|
| 4846 |
|
|
is that roughly the first 400 numbers delivered will be conspicuously
|
| 4847 |
|
|
close to either zero or one.
|
| 4848 |
|
|
</p>
|
| 4849 |
|
|
<p>
|
| 4850 |
|
|
Unfortunately, this is not an innocuous flaw: One of the predefined engines
|
| 4851 |
|
|
in [tr.rand.predef], namely ranlux64_base_01, has w = 48 and would exhibit
|
| 4852 |
|
|
this poor behavior, while the original N1378 proposal states that these
|
| 4853 |
|
|
pre-defined engines are intended to be of "known good properties."
|
| 4854 |
|
|
</p>
|
| 4855 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4856 |
|
|
<p>
|
| 4857 |
|
|
In 5.1.4.4 [tr.rand.eng.sub1], replace the "effects" clause for
|
| 4858 |
|
|
void seed(unsigned long value = 19780503) by
|
| 4859 |
|
|
</p>
|
| 4860 |
|
|
|
| 4861 |
|
|
<blockquote>
|
| 4862 |
|
|
<i>Effects:</i> If <tt>value == 0</tt>, sets value to <tt>19780503</tt>. In any
|
| 4863 |
|
|
case, <del>with a linear congruential generator <tt>lcg</tt>(i) having parameters
|
| 4864 |
|
|
<tt><i>m<sub>lcg</sub></i> = 2147483563</tt>, <tt><i>a<sub>lcg</sub></i> = 40014</tt>,
|
| 4865 |
|
|
<tt><i>c<sub>lcg</sub></i> = 0</tt>, and <tt><i>lcg</i>(0) = value</tt>,</del>
|
| 4866 |
|
|
sets <ins>carry<tt>(-1)</tt> and</ins> <tt>x(-r) … x(-1)</tt>
|
| 4867 |
|
|
<ins>as if executing</ins>
|
| 4868 |
|
|
|
| 4869 |
|
|
<blockquote><pre><ins>
|
| 4870 |
|
|
linear_congruential<unsigned long, 40014, 0, 2147483563> lcg(value);
|
| 4871 |
|
|
seed(lcg);
|
| 4872 |
|
|
</ins></pre></blockquote>
|
| 4873 |
|
|
|
| 4874 |
|
|
<del>to <tt>(<i>lcg</i>(1) · 2<sup>-<i>w</i></sup>) mod 1
|
| 4875 |
|
|
… (<i>lcg</i>(<i>r</i>) · 2<sup>-<i>w</i></sup>) mod 1</tt>,
|
| 4876 |
|
|
respectively. If <tt><i>x</i>(-1) == 0</tt>, sets carry<tt>(-1) = 2<sup>-<i>w</i></sup></tt>,
|
| 4877 |
|
|
else sets carry<tt>(-1) = 0</tt>.</del>
|
| 4878 |
|
|
</blockquote>
|
| 4879 |
|
|
|
| 4880 |
|
|
<p><i>[
|
| 4881 |
|
|
Jens provided revised wording post Mont Tremblant.
|
| 4882 |
|
|
]</i></p>
|
| 4883 |
|
|
|
| 4884 |
|
|
<p><b>Rationale:</b></p>
|
| 4885 |
|
|
<p>
|
| 4886 |
|
|
Jens: I'm using an explicit type here, because fixing the
|
| 4887 |
|
|
prose would probably not qualify for the (with issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#504">504</a> even
|
| 4888 |
|
|
stricter) requirements we have for seed(Gen&).
|
| 4889 |
|
|
</p>
|
| 4890 |
|
|
<hr>
|
| 4891 |
|
|
<a name="513"><h3>513. Size of state for subtract_with_carry_01</h3></a><p><b>Section:</b> TR1 5.1.4.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.eng.sub1"> [tr.rand.eng.sub1]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4892 |
|
|
<p>
|
| 4893 |
|
|
Paragraph 3 begins:
|
| 4894 |
|
|
</p>
|
| 4895 |
|
|
<blockquote>
|
| 4896 |
|
|
The size of the state is r.
|
| 4897 |
|
|
</blockquote>
|
| 4898 |
|
|
<p>
|
| 4899 |
|
|
However, this is not quite consistent with the remainder of the paragraph
|
| 4900 |
|
|
which specifies a total of nr+1 items in the textual representation of
|
| 4901 |
|
|
the state. We recommend the sentence be corrected to match:
|
| 4902 |
|
|
</p>
|
| 4903 |
|
|
<blockquote>
|
| 4904 |
|
|
The size of the state is nr+1.
|
| 4905 |
|
|
</blockquote>
|
| 4906 |
|
|
<p>
|
| 4907 |
|
|
To give meaning to the coefficient n, it may be also desirable to move
|
| 4908 |
|
|
nÕs definition from later in the paragraph. Either of the following
|
| 4909 |
|
|
seem reasonable formulations:
|
| 4910 |
|
|
</p>
|
| 4911 |
|
|
<blockquote>
|
| 4912 |
|
|
With n=..., the size of the state is nr+1.
|
| 4913 |
|
|
</blockquote>
|
| 4914 |
|
|
<blockquote>
|
| 4915 |
|
|
The size of the state is nr+1, where n=... .
|
| 4916 |
|
|
</blockquote>
|
| 4917 |
|
|
<p>
|
| 4918 |
|
|
</p>
|
| 4919 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4920 |
|
|
<p><i>[
|
| 4921 |
|
|
Jens: I plead for "NAD" on the grounds that "size of state" is only
|
| 4922 |
|
|
used as an argument for big-O complexity notation, thus
|
| 4923 |
|
|
constant factors and additions don't count.
|
| 4924 |
|
|
]</i></p>
|
| 4925 |
|
|
<hr>
|
| 4926 |
|
|
<a name="514"><h3>514. Size of state for subtract_with_carry</h3></a><p><b>Section:</b> TR1 5.1.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.eng.sub"> [tr.rand.eng.sub]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4927 |
|
|
<p>
|
| 4928 |
|
|
Paragraph 2 begins:
|
| 4929 |
|
|
</p>
|
| 4930 |
|
|
<blockquote>
|
| 4931 |
|
|
The size of the state is r.
|
| 4932 |
|
|
</blockquote>
|
| 4933 |
|
|
<p>
|
| 4934 |
|
|
However, the next sentence specifies a total of r+1 items in the textual
|
| 4935 |
|
|
representation of the state, r specific xÕs as well as a specific carry.
|
| 4936 |
|
|
This makes a total of r+1 items that constitute the size of the state,
|
| 4937 |
|
|
rather than r.
|
| 4938 |
|
|
</p>
|
| 4939 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 4940 |
|
|
<p>
|
| 4941 |
|
|
We recommend the sentence be corrected to match:
|
| 4942 |
|
|
</p>
|
| 4943 |
|
|
<blockquote>
|
| 4944 |
|
|
The size of the state is r+1.
|
| 4945 |
|
|
</blockquote>
|
| 4946 |
|
|
|
| 4947 |
|
|
<p><i>[
|
| 4948 |
|
|
Jens: I plead for "NAD" on the grounds that "size of state" is only
|
| 4949 |
|
|
used as an argument for big-O complexity notation, thus
|
| 4950 |
|
|
constant factors and additions don't count.
|
| 4951 |
|
|
]</i></p>
|
| 4952 |
|
|
|
| 4953 |
|
|
<hr>
|
| 4954 |
|
|
<a name="515"><h3>515. Random number engine traits</h3></a><p><b>Section:</b> TR1 5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.synopsis"> [tr.rand.synopsis]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 4955 |
|
|
<p>
|
| 4956 |
|
|
To accompany the concept of a pseudo-random number engine as defined in Table 17,
|
| 4957 |
|
|
we propose and recommend an adjunct template, engine_traits, to be declared in
|
| 4958 |
|
|
[tr.rand.synopsis] as:
|
| 4959 |
|
|
</p>
|
| 4960 |
|
|
<blockquote><pre>template< class PSRE >
|
| 4961 |
|
|
class engine_traits;
|
| 4962 |
|
|
</pre></blockquote>
|
| 4963 |
|
|
<p>
|
| 4964 |
|
|
This templateÕs primary purpose would be as an aid to generic programming involving
|
| 4965 |
|
|
pseudo-random number engines. Given only the facilities described in tr1, it would
|
| 4966 |
|
|
be very difficult to produce any algorithms involving the notion of a generic engine.
|
| 4967 |
|
|
The intent of this proposal is to provide, via engine_traits<>, sufficient
|
| 4968 |
|
|
descriptive information to allow an algorithm to employ a pseudo-random number engine
|
| 4969 |
|
|
without regard to its exact type, i.e., as a template parameter.
|
| 4970 |
|
|
</p>
|
| 4971 |
|
|
<p>
|
| 4972 |
|
|
For example, today it is not possible to write an efficient generic function that
|
| 4973 |
|
|
requires any specific number of random bits. More specifically, consider a
|
| 4974 |
|
|
cryptographic application that internally needs 256 bits of randomness per call:
|
| 4975 |
|
|
</p>
|
| 4976 |
|
|
<blockquote><pre>template< class Eng, class InIter, class OutIter >
|
| 4977 |
|
|
void crypto( Eng& e, InIter in, OutIter out );
|
| 4978 |
|
|
</pre></blockquote>
|
| 4979 |
|
|
<p>
|
| 4980 |
|
|
Without knowning the number of bits of randomness produced per call to a provided
|
| 4981 |
|
|
engine, the algorithm has no means of determining how many times to call the engine.
|
| 4982 |
|
|
</p>
|
| 4983 |
|
|
<p>
|
| 4984 |
|
|
In a new section [tr.rand.eng.traits], we proposed to define the engine_traits
|
| 4985 |
|
|
template as:
|
| 4986 |
|
|
</p>
|
| 4987 |
|
|
<blockquote><pre>template< class PSRE >
|
| 4988 |
|
|
class engine_traits
|
| 4989 |
|
|
{
|
| 4990 |
|
|
static std::size_t bits_of_randomness = 0u;
|
| 4991 |
|
|
static std::string name() { return "unknown_engine"; }
|
| 4992 |
|
|
// TODO: other traits here
|
| 4993 |
|
|
};
|
| 4994 |
|
|
</pre></blockquote>
|
| 4995 |
|
|
<p>
|
| 4996 |
|
|
Further, each engine described in [tr.rand.engine] would be accompanied by a
|
| 4997 |
|
|
complete specialization of this new engine_traits template.
|
| 4998 |
|
|
</p>
|
| 4999 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5000 |
|
|
<p>
|
| 5001 |
|
|
|
| 5002 |
|
|
</p>
|
| 5003 |
|
|
<hr>
|
| 5004 |
|
|
<a name="516"><h3>516. Seeding subtract_with_carry_01 using a generator</h3></a><p><b>Section:</b> TR1 5.1.4.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.eng.sub1"> [tr.rand.eng.sub1]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 5005 |
|
|
<p>
|
| 5006 |
|
|
Paragraph 6 says:
|
| 5007 |
|
|
</p>
|
| 5008 |
|
|
<blockquote>
|
| 5009 |
|
|
... obtained by successive invocations of g, ...
|
| 5010 |
|
|
</blockquote>
|
| 5011 |
|
|
<p>
|
| 5012 |
|
|
We recommend instead:
|
| 5013 |
|
|
</p>
|
| 5014 |
|
|
<blockquote>
|
| 5015 |
|
|
... obtained by taking successive invocations of g mod 2**32, ...
|
| 5016 |
|
|
</blockquote>
|
| 5017 |
|
|
<p>
|
| 5018 |
|
|
as the context seems to require only 32-bit quantities be used here.
|
| 5019 |
|
|
</p>
|
| 5020 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5021 |
|
|
<p>
|
| 5022 |
|
|
|
| 5023 |
|
|
</p>
|
| 5024 |
|
|
<hr>
|
| 5025 |
|
|
<a name="517"><h3>517. Should include name in external representation</h3></a><p><b>Section:</b> TR1 5.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.req"> [tr.rand.req]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p>
|
| 5026 |
|
|
<p>
|
| 5027 |
|
|
The last two rows of Table 16 deal with the i/o requirements of an engine,
|
| 5028 |
|
|
specifying that the textual representation of an engineÕs state,
|
| 5029 |
|
|
appropriately formatted, constitute the engineÕs external representation.
|
| 5030 |
|
|
</p>
|
| 5031 |
|
|
<p>
|
| 5032 |
|
|
This seems adequate when an engineÕs type is known. However, it seems
|
| 5033 |
|
|
inadequate in the context of generic code, where it becomes useful and
|
| 5034 |
|
|
perhaps even necessary to determine an engineÕs type via input.
|
| 5035 |
|
|
</p>
|
| 5036 |
|
|
<p>
|
| 5037 |
|
|
</p>
|
| 5038 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5039 |
|
|
<p>
|
| 5040 |
|
|
We therefore recommend that, in each of these two rows of Table 16, the
|
| 5041 |
|
|
text "textual representation" be expanded so as to read "engine name
|
| 5042 |
|
|
followed by the textual representation."
|
| 5043 |
|
|
</p>
|
| 5044 |
|
|
<hr>
|
| 5045 |
|
|
<a name="518"><h3>518. Are insert and erase stable for unordered_multiset and unordered_multimap?</h3></a><p><b>Section:</b> TR1 6.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.hash"> [tr.hash]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Review">Review</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 3 Jul 2005</p>
|
| 5046 |
|
|
<p>
|
| 5047 |
|
|
Issue 371 deals with stability of multiset/multimap under insert and erase
|
| 5048 |
|
|
(i.e. do they preserve the relative order in ranges of equal elements).
|
| 5049 |
|
|
The same issue applies to unordered_multiset and unordered_multimap.
|
| 5050 |
|
|
</p>
|
| 5051 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5052 |
|
|
<p>
|
| 5053 |
|
|
</p>
|
| 5054 |
|
|
<hr>
|
| 5055 |
|
|
<a name="519"><h3>519. Data() undocumented</h3></a><p><b>Section:</b> TR1 6.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.array.array"> [tr.array.array]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 3 Jul 2005</p>
|
| 5056 |
|
|
<p>
|
| 5057 |
|
|
<tt>array<>::data()</tt> is present in the class synopsis, but not documented.
|
| 5058 |
|
|
</p>
|
| 5059 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5060 |
|
|
<p>
|
| 5061 |
|
|
Add a new section, after 6.2.2.3:
|
| 5062 |
|
|
</p>
|
| 5063 |
|
|
<blockquote><pre>T* data()
|
| 5064 |
|
|
const T* data() const;
|
| 5065 |
|
|
</pre></blockquote>
|
| 5066 |
|
|
<p>
|
| 5067 |
|
|
<b>Returns:</b> <tt>elems</tt>.
|
| 5068 |
|
|
</p>
|
| 5069 |
|
|
<p>
|
| 5070 |
|
|
Change 6.2.2.4/2 to:
|
| 5071 |
|
|
</p>
|
| 5072 |
|
|
<blockquote>
|
| 5073 |
|
|
In the case where <tt>N == 0</tt>, <tt>begin() == end()</tt>. The return value
|
| 5074 |
|
|
of <tt>data()</tt> is unspecified.
|
| 5075 |
|
|
</blockquote>
|
| 5076 |
|
|
<hr>
|
| 5077 |
|
|
<a name="520"><h3>520. Result_of and pointers to data members</h3></a><p><b>Section:</b> TR1 3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.func.bind"> [tr.func.bind]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 3 Jul 2005</p>
|
| 5078 |
|
|
<p>
|
| 5079 |
|
|
In the original proposal for binders, the return type of bind() when
|
| 5080 |
|
|
called with a pointer to member data as it's callable object was
|
| 5081 |
|
|
defined to be mem_fn(ptr); when Peter Dimov and I unified the
|
| 5082 |
|
|
descriptions of the TR1 function objects we hoisted the descriptions
|
| 5083 |
|
|
of return types into the INVOKE pseudo-function and into result_of.
|
| 5084 |
|
|
Unfortunately, we left pointer to member data out of result_of, so
|
| 5085 |
|
|
bind doesn't have any specified behavior when called with a pointer
|
| 5086 |
|
|
to member data.
|
| 5087 |
|
|
</p>
|
| 5088 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5089 |
|
|
<p><i>[
|
| 5090 |
|
|
Pete and Peter will provide wording.
|
| 5091 |
|
|
]</i></p>
|
| 5092 |
|
|
<hr>
|
| 5093 |
|
|
<a name="521"><h3>521. Garbled requirements for argument_type in reference_wrapper</h3></a><p><b>Section:</b> TR1 2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.util.refwrp.refwrp"> [tr.util.refwrp.refwrp]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 3 Jul 2005</p>
|
| 5094 |
|
|
<p>
|
| 5095 |
|
|
2.1.2/3, second bullet item currently says that reference_wrapper<T> is
|
| 5096 |
|
|
derived from unary_function<T, R> if T is:
|
| 5097 |
|
|
</p>
|
| 5098 |
|
|
<blockquote>
|
| 5099 |
|
|
a pointer to member function type with cv-qualifier cv and no arguments;
|
| 5100 |
|
|
the type T1 is cv T* and R is the return type of the pointer to member function;
|
| 5101 |
|
|
</blockquote>
|
| 5102 |
|
|
<p>
|
| 5103 |
|
|
The type of T1 can't be cv T*, 'cause that's a pointer to a pointer to member
|
| 5104 |
|
|
function. It should be a pointer to the class that T is a pointer to member of.
|
| 5105 |
|
|
Like this:
|
| 5106 |
|
|
</p>
|
| 5107 |
|
|
<blockquote>
|
| 5108 |
|
|
a pointer to a member function R T0::f() cv (where cv represents the member
|
| 5109 |
|
|
function's cv-qualifiers); the type T1 is cv T0*
|
| 5110 |
|
|
</blockquote>
|
| 5111 |
|
|
<p>
|
| 5112 |
|
|
Similarly, bullet item 2 in 2.1.2/4 should be:
|
| 5113 |
|
|
</p>
|
| 5114 |
|
|
<blockquote>
|
| 5115 |
|
|
a pointer to a member function R T0::f(T2) cv (where cv represents the member
|
| 5116 |
|
|
function's cv-qualifiers); the type T1 is cv T0*
|
| 5117 |
|
|
</blockquote>
|
| 5118 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5119 |
|
|
<hr>
|
| 5120 |
|
|
<a name="522"></a><h3><a name="522">522. Tuple doesn't define swap</a></h3><p><b>Section:</b> TR1 6.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.tuple"> [tr.tuple]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Andy Koenig <b>Date:</b> 3 Jul 2005</p>
|
| 5121 |
|
|
<p>
|
| 5122 |
|
|
Tuple doesn't define swap(). It should.
|
| 5123 |
|
|
</p>
|
| 5124 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5125 |
|
|
<hr>
|
| 5126 |
|
|
<a name="523"><h3>523. regex case-insensitive character ranges are unimplementable as specified</h3></a><p><b>Section:</b> TR1 7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.re"> [tr.re]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Eric Niebler <b>Date:</b> 1 Jul 2005</p>
|
| 5127 |
|
|
<p>
|
| 5128 |
|
|
A problem with TR1 regex is currently being discussed on the Boost
|
| 5129 |
|
|
developers list. It involves the handling of case-insensitive matching
|
| 5130 |
|
|
of character ranges such as [Z-a]. The proper behavior (according to the
|
| 5131 |
|
|
ECMAScript standard) is unimplementable given the current specification
|
| 5132 |
|
|
of the TR1 regex_traits<> class template. John Maddock, the author of
|
| 5133 |
|
|
the TR1 regex proposal, agrees there is a problem. The full discussion
|
| 5134 |
|
|
can be found at http://lists.boost.org/boost/2005/06/28850.php (first
|
| 5135 |
|
|
message copied below). We don't have any recommendations as yet.
|
| 5136 |
|
|
</p>
|
| 5137 |
|
|
<p>
|
| 5138 |
|
|
-- Begin original message --
|
| 5139 |
|
|
</p>
|
| 5140 |
|
|
<p>
|
| 5141 |
|
|
The situation of interest is described in the ECMAScript specification
|
| 5142 |
|
|
(ECMA-262), section 15.10.2.15:
|
| 5143 |
|
|
</p>
|
| 5144 |
|
|
<p>
|
| 5145 |
|
|
"Even if the pattern ignores case, the case of the two ends of a range
|
| 5146 |
|
|
is significant in determining which characters belong to the range.
|
| 5147 |
|
|
Thus, for example, the pattern /[E-F]/i matches only the letters E, F,
|
| 5148 |
|
|
e, and f, while the pattern /[E-f]/i matches all upper and lower-case
|
| 5149 |
|
|
ASCII letters as well as the symbols [, \, ], ^, _, and `."
|
| 5150 |
|
|
</p>
|
| 5151 |
|
|
<p>
|
| 5152 |
|
|
A more interesting case is what should happen when doing a
|
| 5153 |
|
|
case-insentitive match on a range such as [Z-a]. It should match z, Z,
|
| 5154 |
|
|
a, A and the symbols [, \, ], ^, _, and `. This is not what happens with
|
| 5155 |
|
|
Boost.Regex (it throws an exception from the regex constructor).
|
| 5156 |
|
|
</p>
|
| 5157 |
|
|
<p>
|
| 5158 |
|
|
The tough pill to swallow is that, given the specification in TR1, I
|
| 5159 |
|
|
don't think there is any effective way to handle this situation.
|
| 5160 |
|
|
According to the spec, case-insensitivity is handled with
|
| 5161 |
|
|
regex_traits<>::translate_nocase(CharT) -- two characters are equivalent
|
| 5162 |
|
|
if they compare equal after both are sent through the translate_nocase
|
| 5163 |
|
|
function. But I don't see any way of using this translation function to
|
| 5164 |
|
|
make character ranges case-insensitive. Consider the difficulty of
|
| 5165 |
|
|
detecting whether "z" is in the range [Z-a]. Applying the transformation
|
| 5166 |
|
|
to "z" has no effect (it is essentially std::tolower). And we're not
|
| 5167 |
|
|
allowed to apply the transformation to the ends of the range, because as
|
| 5168 |
|
|
ECMA-262 says, "the case of the two ends of a range is significant."
|
| 5169 |
|
|
</p>
|
| 5170 |
|
|
<p>
|
| 5171 |
|
|
So AFAICT, TR1 regex is just broken, as is Boost.Regex. One possible fix
|
| 5172 |
|
|
is to redefine translate_nocase to return a string_type containing all
|
| 5173 |
|
|
the characters that should compare equal to the specified character. But
|
| 5174 |
|
|
this function is hard to implement for Unicode, and it doesn't play nice
|
| 5175 |
|
|
with the existing ctype facet. What a mess!
|
| 5176 |
|
|
</p>
|
| 5177 |
|
|
<p>
|
| 5178 |
|
|
-- End original message --
|
| 5179 |
|
|
</p>
|
| 5180 |
|
|
|
| 5181 |
|
|
<p><i>[
|
| 5182 |
|
|
John Maddock adds:
|
| 5183 |
|
|
]</i></p>
|
| 5184 |
|
|
|
| 5185 |
|
|
<p>
|
| 5186 |
|
|
One small correction, I have since found that ICU's regex package does
|
| 5187 |
|
|
implement this correctly, using a similar mechanism to the current
|
| 5188 |
|
|
TR1.Regex.
|
| 5189 |
|
|
</p>
|
| 5190 |
|
|
<p>
|
| 5191 |
|
|
Given an expression [c1-c2] that is compiled as case insensitive it:
|
| 5192 |
|
|
</p>
|
| 5193 |
|
|
<p>
|
| 5194 |
|
|
Enumerates every character in the range c1 to c2 and converts it to it's
|
| 5195 |
|
|
case folded equivalent. That case folded character is then used a key to a
|
| 5196 |
|
|
table of equivalence classes, and each member of the class is added to the
|
| 5197 |
|
|
list of possible matches supported by the character-class. This second step
|
| 5198 |
|
|
isn't possible with our current traits class design, but isn't necessary if
|
| 5199 |
|
|
the input text is also converted to a case-folded equivalent on the fly.
|
| 5200 |
|
|
</p>
|
| 5201 |
|
|
<p>
|
| 5202 |
|
|
ICU applies similar brute force mechanisms to character classes such as
|
| 5203 |
|
|
[[:lower:]] and [[:word:]], however these are at least cached, so the impact
|
| 5204 |
|
|
is less noticeable in this case.
|
| 5205 |
|
|
</p>
|
| 5206 |
|
|
<p>
|
| 5207 |
|
|
Quick and dirty performance comparisons show that expressions such as
|
| 5208 |
|
|
"[X-\\x{fff0}]+" are indeed very slow to compile with ICU (about 200 times
|
| 5209 |
|
|
slower than a "normal" expression). For an application that uses a lot of
|
| 5210 |
|
|
regexes this could have a noticeable performance impact. ICU also has an
|
| 5211 |
|
|
advantage in that it knows the range of valid characters codes: code points
|
| 5212 |
|
|
outside that range are assumed not to require enumeration, as they can not
|
| 5213 |
|
|
be part of any equivalence class. I presume that if we want the TR1.Regex
|
| 5214 |
|
|
to work with arbitrarily large character sets enumeration really does become
|
| 5215 |
|
|
impractical.
|
| 5216 |
|
|
</p>
|
| 5217 |
|
|
<p>
|
| 5218 |
|
|
Finally note that Unicode has:
|
| 5219 |
|
|
</p>
|
| 5220 |
|
|
<p>
|
| 5221 |
|
|
Three cases (upper, lower and title).
|
| 5222 |
|
|
One to many, and many to one case transformations.
|
| 5223 |
|
|
Character that have context sensitive case translations - for example an
|
| 5224 |
|
|
uppercase sigma has two different lowercase forms - the form chosen depends
|
| 5225 |
|
|
on context(is it end of a word or not), a caseless match for an upper case
|
| 5226 |
|
|
sigma should match either of the lower case forms, which is why case folding
|
| 5227 |
|
|
is often approximated by tolower(toupper(c)).
|
| 5228 |
|
|
</p>
|
| 5229 |
|
|
<p>
|
| 5230 |
|
|
Probably we need some way to enumerate character equivalence classes,
|
| 5231 |
|
|
including digraphs (either as a result or an input), and some way to tell
|
| 5232 |
|
|
whether the next character pair is a valid digraph in the current locale.
|
| 5233 |
|
|
</p>
|
| 5234 |
|
|
<p>
|
| 5235 |
|
|
Hoping this doesn't make this even more complex that it was already,
|
| 5236 |
|
|
</p>
|
| 5237 |
|
|
|
| 5238 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5239 |
|
|
<hr>
|
| 5240 |
|
|
<a name="524"><h3>524. regex named character classes and case-insensitivity don't mix</h3></a><p><b>Section:</b> TR1 7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.re"> [tr.re]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Eric Niebler <b>Date:</b> 1 Jul 2005</p>
|
| 5241 |
|
|
<p>
|
| 5242 |
|
|
This defect is also being discussed on the Boost developers list. The
|
| 5243 |
|
|
full discussion can be found here:
|
| 5244 |
|
|
http://lists.boost.org/boost/2005/07/29546.php
|
| 5245 |
|
|
</p>
|
| 5246 |
|
|
<p>
|
| 5247 |
|
|
-- Begin original message --
|
| 5248 |
|
|
</p>
|
| 5249 |
|
|
<p>
|
| 5250 |
|
|
Also, I may have found another issue, closely related to the one under
|
| 5251 |
|
|
discussion. It regards case-insensitive matching of named character
|
| 5252 |
|
|
classes. The regex_traits<> provides two functions for working with
|
| 5253 |
|
|
named char classes: lookup_classname and isctype. To match a char class
|
| 5254 |
|
|
such as [[:alpha:]], you pass "alpha" to lookup_classname and get a
|
| 5255 |
|
|
bitmask. Later, you pass a char and the bitmask to isctype and get a
|
| 5256 |
|
|
bool yes/no answer.
|
| 5257 |
|
|
</p>
|
| 5258 |
|
|
<p>
|
| 5259 |
|
|
But how does case-insensitivity work in this scenario? Suppose we're
|
| 5260 |
|
|
doing a case-insensitive match on [[:lower:]]. It should behave as if it
|
| 5261 |
|
|
were [[:lower:][:upper:]], right? But there doesn't seem to be enough
|
| 5262 |
|
|
smarts in the regex_traits interface to do this.
|
| 5263 |
|
|
</p>
|
| 5264 |
|
|
<p>
|
| 5265 |
|
|
Imagine I write a traits class which recognizes [[:fubar:]], and the
|
| 5266 |
|
|
"fubar" char class happens to be case-sensitive. How is the regex engine
|
| 5267 |
|
|
to know that? And how should it do a case-insensitive match of a
|
| 5268 |
|
|
character against the [[:fubar:]] char class? John, can you confirm this
|
| 5269 |
|
|
is a legitimate problem?
|
| 5270 |
|
|
</p>
|
| 5271 |
|
|
<p>
|
| 5272 |
|
|
I see two options:
|
| 5273 |
|
|
</p>
|
| 5274 |
|
|
<p>
|
| 5275 |
|
|
1) Add a bool icase parameter to lookup_classname. Then,
|
| 5276 |
|
|
lookup_classname( "upper", true ) will know to return lower|upper
|
| 5277 |
|
|
instead of just upper.
|
| 5278 |
|
|
</p>
|
| 5279 |
|
|
<p>
|
| 5280 |
|
|
2) Add a isctype_nocase function
|
| 5281 |
|
|
</p>
|
| 5282 |
|
|
<p>
|
| 5283 |
|
|
I prefer (1) because the extra computation happens at the time the
|
| 5284 |
|
|
pattern is compiled rather than when it is executed.
|
| 5285 |
|
|
</p>
|
| 5286 |
|
|
<p>
|
| 5287 |
|
|
-- End original message --
|
| 5288 |
|
|
</p>
|
| 5289 |
|
|
|
| 5290 |
|
|
<p>
|
| 5291 |
|
|
For what it's worth, John has also expressed his preference for option
|
| 5292 |
|
|
(1) above.
|
| 5293 |
|
|
</p>
|
| 5294 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5295 |
|
|
<hr>
|
| 5296 |
|
|
<a name="525"><h3>525. type traits definitions not clear</h3></a><p><b>Section:</b> TR1 4.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.meta.unary"> [tr.meta.unary]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Robert Klarer <b>Date:</b> 11 Jul 2005</p>
|
| 5297 |
|
|
<p>
|
| 5298 |
|
|
It is not completely clear how the primary type traits deal with
|
| 5299 |
|
|
cv-qualified types. And several of the secondary type traits
|
| 5300 |
|
|
seem to be lacking a definition.
|
| 5301 |
|
|
</p>
|
| 5302 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5303 |
|
|
<hr>
|
| 5304 |
|
|
<a name="526"></a><h3><a name="526">526. Is it undefined if a function in the standard changes in parameters?</a></h3><p><b>Section:</b> 23.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.sequence.reqmts"> [lib.sequence.reqmts]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Chris Jefferson <b>Date:</b> 14 Sep 2005</p>
|
| 5305 |
|
|
<p>
|
| 5306 |
|
|
Problem: There are a number of places in the C++ standard library where
|
| 5307 |
|
|
it is possible to write what appear to be sensible ways of calling
|
| 5308 |
|
|
functions, but which can cause problems in some (or all)
|
| 5309 |
|
|
implementations, as they cause the values given to the function to be
|
| 5310 |
|
|
changed in a way not specified in standard (and therefore not coded to
|
| 5311 |
|
|
correctly work). These fall into two similar categories.
|
| 5312 |
|
|
</p>
|
| 5313 |
|
|
|
| 5314 |
|
|
<p>
|
| 5315 |
|
|
1) Parameters taken by const reference can be changed during execution
|
| 5316 |
|
|
of the function
|
| 5317 |
|
|
</p>
|
| 5318 |
|
|
|
| 5319 |
|
|
<p>
|
| 5320 |
|
|
Examples:
|
| 5321 |
|
|
</p>
|
| 5322 |
|
|
|
| 5323 |
|
|
<p>
|
| 5324 |
|
|
Given std::vector<int> v:
|
| 5325 |
|
|
</p>
|
| 5326 |
|
|
<p>
|
| 5327 |
|
|
v.insert(v.begin(), v[2]);
|
| 5328 |
|
|
</p>
|
| 5329 |
|
|
<p>
|
| 5330 |
|
|
v[2] can be changed by moving elements of vector
|
| 5331 |
|
|
</p>
|
| 5332 |
|
|
|
| 5333 |
|
|
|
| 5334 |
|
|
<p>
|
| 5335 |
|
|
Given std::list<int> l:
|
| 5336 |
|
|
</p>
|
| 5337 |
|
|
<p>
|
| 5338 |
|
|
l.remove(*l.begin());
|
| 5339 |
|
|
</p>
|
| 5340 |
|
|
<p>
|
| 5341 |
|
|
Will delete the first element, and then continue trying to access it.
|
| 5342 |
|
|
This is particularily vicious, as it will appear to work in almost all
|
| 5343 |
|
|
cases.
|
| 5344 |
|
|
</p>
|
| 5345 |
|
|
|
| 5346 |
|
|
<p>
|
| 5347 |
|
|
2) A range is given which changes during the execution of the function:
|
| 5348 |
|
|
Similarly,
|
| 5349 |
|
|
</p>
|
| 5350 |
|
|
|
| 5351 |
|
|
<p>
|
| 5352 |
|
|
v.insert(v.begin(), v.begin()+4, v.begin()+6);
|
| 5353 |
|
|
</p>
|
| 5354 |
|
|
|
| 5355 |
|
|
<p>
|
| 5356 |
|
|
This kind of problem has been partly covered in some cases. For example
|
| 5357 |
|
|
std::copy(first, last, result) states that result cannot be in the range
|
| 5358 |
|
|
[first, last). However, does this cover the case where result is a
|
| 5359 |
|
|
reverse_iterator built from some iterator in the range [first, last)?
|
| 5360 |
|
|
Also, std::copy would still break if result was reverse_iterator(last +
|
| 5361 |
|
|
1), yet this is not forbidden by the standard
|
| 5362 |
|
|
</p>
|
| 5363 |
|
|
|
| 5364 |
|
|
<p>
|
| 5365 |
|
|
Solution:
|
| 5366 |
|
|
</p>
|
| 5367 |
|
|
|
| 5368 |
|
|
<p>
|
| 5369 |
|
|
One option would be to try to more carefully limit the requirements of
|
| 5370 |
|
|
each function. There are many functions which would have to be checked.
|
| 5371 |
|
|
However as has been shown in the std::copy case, this may be difficult.
|
| 5372 |
|
|
A simpler, more global option would be to somewhere insert text similar to:
|
| 5373 |
|
|
</p>
|
| 5374 |
|
|
|
| 5375 |
|
|
<p>
|
| 5376 |
|
|
If the execution of any function would change either any values passed
|
| 5377 |
|
|
by reference or any value in any range passed to a function in a way not
|
| 5378 |
|
|
defined in the definition of that function, the result is undefined.
|
| 5379 |
|
|
</p>
|
| 5380 |
|
|
|
| 5381 |
|
|
<p>
|
| 5382 |
|
|
Such code would have to at least cover chapters 23 and 25 (the sections
|
| 5383 |
|
|
I read through carefully). I can see no harm on applying it to much of
|
| 5384 |
|
|
the rest of the standard.
|
| 5385 |
|
|
</p>
|
| 5386 |
|
|
|
| 5387 |
|
|
<p>
|
| 5388 |
|
|
Some existing parts of the standard could be improved to fit with this,
|
| 5389 |
|
|
for example the requires for 25.2.1 (Copy) could be adjusted to:
|
| 5390 |
|
|
</p>
|
| 5391 |
|
|
|
| 5392 |
|
|
<p>
|
| 5393 |
|
|
Requires: For each non-negative integer n < (last - first), assigning to
|
| 5394 |
|
|
*(result + n) must not alter any value in the range [first + n, last).
|
| 5395 |
|
|
</p>
|
| 5396 |
|
|
|
| 5397 |
|
|
<p>
|
| 5398 |
|
|
However, this may add excessive complication.
|
| 5399 |
|
|
</p>
|
| 5400 |
|
|
|
| 5401 |
|
|
<p>
|
| 5402 |
|
|
One other benefit of clearly introducing this text is that it would
|
| 5403 |
|
|
allow a number of small optimisations, such as caching values passed
|
| 5404 |
|
|
by const reference.
|
| 5405 |
|
|
</p>
|
| 5406 |
|
|
|
| 5407 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5408 |
|
|
<p>
|
| 5409 |
|
|
</p>
|
| 5410 |
|
|
<hr>
|
| 5411 |
|
|
<a name="527"><h3>527. tr1::bind has lost its Throws clause</h3></a><p><b>Section:</b> TR1 3.6.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.func.bind.bind"> [tr.func.bind.bind]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Peter Dimov <b>Date:</b> 01 Oct 2005</p>
|
| 5412 |
|
|
<p>
|
| 5413 |
|
|
The original bind proposal gives the guarantee that tr1::bind(f, t1,
|
| 5414 |
|
|
..., tN) does not throw when the copy constructors of f, t1, ..., tN
|
| 5415 |
|
|
don't.
|
| 5416 |
|
|
</p>
|
| 5417 |
|
|
|
| 5418 |
|
|
<p>
|
| 5419 |
|
|
This guarantee is not present in the final version of TR1.
|
| 5420 |
|
|
</p>
|
| 5421 |
|
|
|
| 5422 |
|
|
<p>
|
| 5423 |
|
|
I'm pretty certain that we never removed it on purpose. Editorial omission? :-)
|
| 5424 |
|
|
</p>
|
| 5425 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5426 |
|
|
<p>
|
| 5427 |
|
|
</p>
|
| 5428 |
|
|
<hr>
|
| 5429 |
|
|
<a name="528"><h3>528. TR1: issue 6.19 vs 6.3.4.3/2 (and 6.3.4.5/2)</h3></a><p><b>Section:</b> TR1 6.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.unord.unord"> [tr.unord.unord]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Paolo Carlini <b>Date:</b> 12 Oct 2005</p>
|
| 5430 |
|
|
<p>
|
| 5431 |
|
|
while implementing the resolution of issue 6.19 I'm noticing the
|
| 5432 |
|
|
following: according to 6.3.4.3/2 (and 6.3.4.5/2), for unordered_set and
|
| 5433 |
|
|
unordered_multiset:
|
| 5434 |
|
|
</p>
|
| 5435 |
|
|
|
| 5436 |
|
|
<blockquote>
|
| 5437 |
|
|
"The iterator and const_iterator types are both const types. It is
|
| 5438 |
|
|
unspecified whether they are the same type"
|
| 5439 |
|
|
</blockquote>
|
| 5440 |
|
|
|
| 5441 |
|
|
<p>
|
| 5442 |
|
|
Now, according to the resolution of 6.19, we have overloads of insert
|
| 5443 |
|
|
with hint and erase (single and range) both for iterator and
|
| 5444 |
|
|
const_iterator, which, AFAICS, can be meaningful at the same time *only*
|
| 5445 |
|
|
if iterator and const_iterator *are* in fact different types.
|
| 5446 |
|
|
</p>
|
| 5447 |
|
|
<p>
|
| 5448 |
|
|
Then, iterator and const_iterator are *required* to be different types?
|
| 5449 |
|
|
Or that is an unintended consequence? Maybe the overloads for plain
|
| 5450 |
|
|
iterators should be added only to unordered_map and unordered_multimap?
|
| 5451 |
|
|
Or, of course, I'm missing something?
|
| 5452 |
|
|
</p>
|
| 5453 |
|
|
|
| 5454 |
|
|
<p><b>Proposed resolution:</b></p>
|
| 5455 |
|
|
<p>
|
| 5456 |
|
|
Add to 6.3.4.3p2 (and 6.3.4.5p2):
|
| 5457 |
|
|
</p>
|
| 5458 |
|
|
<p>
|
| 5459 |
|
|
2 ... The iterator and const_iterator types are both <del>const</del>
|
| 5460 |
|
|
<ins>constant</ins> iterator types.
|
| 5461 |
|
|
It is unspecified whether they are the same type. <ins>If they are the
|
| 5462 |
|
|
same type, those signatures that become otherwise indistinguishable
|
| 5463 |
|
|
collapse into a single signature.</ins>
|
| 5464 |
|
|
</p>
|
| 5465 |
|
|
|
| 5466 |
|
|
<p>----- End of document -----</p>
|
| 5467 |
|
|
</body></html>
|