| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> |
| <html><head><title>C++ Standard Library Active Issues List</title> |
| |
| <style>ins {background-color:#FFFFA0} |
| del {background-color:#FFFFA0}</style></head> |
| |
| <body bgcolor="#ffffff" text="#000000"> |
| <table> |
| <tbody><tr> |
| <td align="left">Doc. no.</td> |
| <td align="left">N2130=06-0200</td> |
| </tr> |
| <tr> |
| <td align="left">Date:</td> |
| <td align="left">2006-11-03</td> |
| </tr> |
| <tr> |
| <td align="left">Project:</td> |
| <td align="left">Programming Language C++</td> |
| </tr> |
| <tr> |
| <td align="left">Reply to:</td> |
| <td align="left">Howard Hinnant <howard.hinnant@gmail.com></td> |
| </tr> |
| </tbody></table> |
| <h1>C++ Standard Library Active Issues List (Revision R45)</h1> |
| <p>Reference ISO/IEC IS 14882:1998(E)</p> |
| <p>Also see:</p> |
| <ul> |
| <li> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-toc.html">Table of Contents</a> for all library issues.</li> |
| <li> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html">Index by Section</a> for all library issues.</li> |
| <li> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html">Index by Status</a> for all library issues.</li> |
| <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html">Library Defect Reports List</a></li> |
| <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html">Library Closed Issues List</a></li> |
| </ul> |
| <p>The purpose of this document is to record the status of issues |
| which have come before the Library Working Group (LWG) of the ANSI |
| (J16) and ISO (WG21) C++ Standards Committee. Issues represent |
| potential defects in the ISO/IEC IS 14882:1998(E) document. Issues |
| are not to be used to request new features. </p> |
| |
| <p>This document contains only library issues which are actively being |
| considered by the Library Working Group. That is, issues which have a |
| status of <a href="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>, |
| <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 |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html">Library Defect Reports List</a> for issues considered defects and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html">Library Closed Issues List</a> for issues considered closed.</p> |
| |
| <p>The issues in these lists are not necessarily formal ISO Defect |
| Reports (DR's). While some issues will eventually be elevated to |
| official Defect Report status, other issues will be disposed of in |
| other ways. See <a href="#Status">Issue Status</a>.</p> |
| |
| <p>This document is in an experimental format designed for both |
| viewing via a world-wide web browser and hard-copy printing. It |
| is available as an HTML file for browsing or PDF file for |
| printing.</p> |
| |
| <p>Prior to Revision 14, library issues lists existed in two slightly |
| different versions; a Committee Version and a Public |
| Version. Beginning with Revision 14 the two versions were combined |
| into a single version.</p> |
| |
| <p>This document includes <i>[bracketed italicized notes]</i> as a |
| reminder to the LWG of current progress on issues. Such notes are |
| strictly unofficial and should be read with caution as they may be |
| incomplete or incorrect. Be aware that LWG support for a particular |
| resolution can quickly change if new viewpoints or killer examples are |
| presented in subsequent discussions.</p> |
| |
| <p>For the most current official version of this document see |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/">http://www.open-std.org/jtc1/sc22/wg21/</a>. |
| Requests for further information about this document should include |
| the document number above, reference ISO/IEC 14882:1998(E), and be |
| submitted to Information Technology Industry Council (ITI), 1250 Eye |
| Street NW, Washington, DC 20005.</p> |
| |
| <p>Public information as to how to obtain a copy of the C++ Standard, |
| join the standards committee, submit an issue, or comment on an issue |
| can be found in the comp.std.c++ FAQ. |
| Public discussion of C++ Standard related issues occurs on <a href="news://comp.std.c++/">news:comp.std.c++</a>. |
| </p> |
| |
| <p>For committee members, files available on the committee's private |
| web site include the HTML version of the Standard itself. HTML |
| hyperlinks from this issues list to those files will only work for |
| committee members who have downloaded them into the same disk |
| directory as the issues list files. </p> |
| <h2>Revision History</h2> |
| <ul> |
| <li>R45: |
| 2006-11-03 post-Portland mailing. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#520">520</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#521">521</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530">530</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#535">535</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#537">537</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#538">538</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#540">540</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#541">541</a> to WP. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#516">516</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#544">544</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#554">554</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#555">555</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#558">558</a> to NAD. |
| Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#569">569</a> to Dup. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518">518</a>, <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#524">524</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#542">542</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#556">556</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#557">557</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#559">559</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#597">597</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#606">606</a> to Open. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#543">543</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#545">545</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#598">598</a> - <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#603">603</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#605">605</a> to Ready. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#531">531</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#551">551</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#604">604</a> to Review. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#593">593</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#609">609</a>. |
| </li> |
| <li>R44: |
| 2006-09-08 pre-Portland mailing. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#583">583</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#592">592</a>. |
| </li> |
| <li>R43: |
| 2006-06-23 mid-term mailing. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#575">575</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#582">582</a>. |
| Reopened <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#255">255</a>. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#520">520</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#541">541</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#544">544</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#569">569</a> to Tentatively Ready. |
| </li> |
| <li>R42: |
| 2006-04-21 post-Berlin mailing. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#567">567</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#572">572</a>. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#499">499</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#501">501</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#506">506</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#509">509</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#511">511</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#513">513</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#514">514</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#517">517</a> to NAD. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#502">502</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#503">503</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#515">515</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#516">516</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#522">522</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#525">525</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#529">529</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#532">532</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#536">536</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#539">539</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#548">548</a> to Open. |
| Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#521">521</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530">530</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#531">531</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#535">535</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#537">537</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#538">538</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#540">540</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a> to Ready. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#247">247</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#294">294</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#362">362</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#369">369</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#371">371</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#376">376</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#384">384</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#475">475</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#478">478</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#495">495</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#497">497</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#505">505</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#507">507</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#508">508</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#519">519</a> to WP. |
| Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#534">534</a> to Review. |
| </li> |
| <li>R41: |
| 2006-02-24 pre-Berlin mailing. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#536">536</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#566">566</a>. |
| Moved <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#342">342</a> from Ready to Open. |
| Reopened <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#309">309</a>. |
| </li> |
| <li>R40: |
| 2005-12-16 mid-term mailing. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#529">529</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#535">535</a>. |
| </li> |
| <li>R39: |
| 2005-10-14 post-Mont Tremblant mailing. |
| 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>. |
| 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. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#247">247</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.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-defects.html#362">362</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#369">369</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#371">371</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#376">376</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#384">384</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#475">475</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#478">478</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#495">495</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#497">497</a> from Review to Ready. |
| 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-closed.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#506">506</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#509">509</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#510">510</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#511">511</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#513">513</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#514">514</a> from New to Open. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#505">505</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#507">507</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#508">508</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#519">519</a> from New to Ready. |
| Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#500">500</a> from New to NAD. |
| Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518">518</a> from New to Review. |
| </li> |
| <li>R38: |
| 2005-07-03 pre-Mont Tremblant mailing. |
| Merged open TR1 issues in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#522">522</a>. |
| 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> |
| </li> |
| <li>R37: |
| 2005-06 mid-term mailing. |
| 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>. |
| </li> |
| <li>R36: |
| 2005-04 post-Lillehammer mailing. All issues in "ready" status except |
| 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 |
| previously in "DR" status were moved to "WP". |
| </li> |
| <li>R35: |
| 2005-03 pre-Lillehammer mailing. |
| </li> |
| <li>R34: |
| 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>. |
| </li> |
| <li>R33: |
| 2004-11 post-Redmond mailing. Reflects actions taken in Redmond. |
| </li> |
| <li>R32: |
| 2004-09 pre-Redmond mailing: reflects new proposed resolutions and |
| new issues received after the 2004-07 mailing. Added |
| 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>. |
| </li> |
| <li>R31: |
| 2004-07 mid-term mailing: reflects new proposed resolutions and |
| new issues received after the post-Sydney mailing. Added |
| 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-defects.html#478">478</a>. |
| </li> |
| <li>R30: |
| Post-Sydney mailing: reflects decisions made at the Sydney meeting. |
| Voted all "Ready" issues from R29 into the working paper. |
| 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>. |
| </li> |
| <li>R29: |
| 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>. |
| </li> |
| <li>R28: |
| Post-Kona mailing: reflects decisions made at the Kona meeting. |
| 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>. |
| </li> |
| <li>R27: |
| 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>. |
| </li> |
| <li>R26: |
| Post-Oxford mailing: reflects decisions made at the Oxford meeting. |
| All issues in Ready status were voted into DR status. All issues in |
| DR status were voted into WP status. |
| </li> |
| <li>R25: |
| 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>. |
| </li> |
| <li>R24: |
| Post-Santa Cruz mailing: reflects decisions made at the Santa Cruz |
| 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 |
| 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 |
| 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 |
| concerns with <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a> involve wording. |
| </li> |
| <li>R23: |
| 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>. |
| Moved issues in the TC to TC status. |
| </li> |
| <li>R22: |
| Post-Curaçao mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#362">362</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#366">366</a>. |
| </li> |
| <li>R21: |
| 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>. |
| </li> |
| <li>R20: |
| Post-Redmond mailing; reflects actions taken in Redmond. Added |
| 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 |
| <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 |
| not discussed at the meeting. |
| |
| All Ready issues were moved to DR status, with the exception of issues |
| <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>. |
| |
| Noteworthy issues discussed at Redmond include |
| <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>, |
| <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>. |
| </li> |
| <li>R19: |
| Pre-Redmond mailing. Added new issues |
| <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>. |
| </li> |
| <li>R18: |
| Post-Copenhagen mailing; reflects actions taken in Copenhagen. |
| 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 |
| 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>. |
| |
| Changed status of 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#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> |
| <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> |
| <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> |
| <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> |
| <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> |
| <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> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#268">268</a> |
| to DR. |
| |
| Changed status of 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#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> |
| <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> |
| <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> |
| <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> |
| <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> |
| <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> |
| <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> |
| <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> |
| <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> |
| to Ready. |
| |
| Closed issues |
| <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> |
| <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> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#314">314</a> |
| as NAD. |
| |
| </li> |
| <li>R17: |
| Pre-Copenhagen mailing. Converted issues list to XML. Added proposed |
| resolutions for issues <a href="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>. |
| 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>. |
| </li> |
| <li>R16: |
| post-Toronto mailing; reflects actions taken in Toronto. Added new |
| 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 |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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>, |
| <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 |
| 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 |
| <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 |
| 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 |
| 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 |
| the bug in enough places. |
| </li> |
| <li>R15: |
| pre-Toronto mailing. Added issues |
| <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 |
| changes so that we pass Weblint tests. |
| </li> |
| <li>R14: |
| post-Tokyo II mailing; reflects committee actions taken in |
| 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) |
| </li> |
| <li>R13: |
| 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>. |
| </li> |
| <li>R12: |
| pre-Tokyo II mailing: Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199">199</a> to |
| <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 |
| of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#29">29</a>. Add further rationale to issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#178">178</a>. |
| </li> |
| <li>R11: |
| post-Kona mailing: Updated to reflect LWG and full committee actions |
| in Kona (99-0048/N1224). Note changed resolution of issues |
| <a href="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> |
| 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 |
| "closed" documents. Changed the proposed resolution of issue |
| <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 |
| of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#38">38</a>. |
| </li> |
| <li>R10: |
| pre-Kona updated. Added proposed resolutions <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#83">83</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#91">91</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#92">92</a>, |
| <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 |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#195">195</a>. (99-0033/D1209, 14 Oct 99) |
| </li> |
| <li>R9: |
| pre-Kona mailing. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#140">140</a> to |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#189">189</a>. Issues list split into separate "active" and |
| "closed" documents. (99-0030/N1206, 25 Aug 99) |
| </li> |
| <li>R8: |
| post-Dublin mailing. Updated to reflect LWG and full committee actions |
| in Dublin. (99-0016/N1193, 21 Apr 99) |
| </li> |
| <li>R7: |
| pre-Dublin updated: Added issues <a href="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>, |
| <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>, |
| <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>, |
| <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) |
| </li> |
| <li>R6: |
| 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>, |
| and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#129">129</a>. (99-0007/N1194, 22 Feb 99) |
| </li> |
| <li>R5: |
| 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 |
| <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 |
| for making list public. (30 Dec 98) |
| </li> |
| <li>R4: |
| post-Santa Cruz II updated: Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#110">110</a>, |
| <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 |
| issues corrected. (22 Oct 98) |
| </li> |
| <li>R3: |
| 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> |
| added, many issues updated to reflect LWG consensus (12 Oct 98) |
| </li> |
| <li>R2: |
| 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, |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#17">17</a> updated. (29 Sep 98) |
| </li> |
| <li>R1: |
| 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 |
| format, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#64">64</a> title. (17 Sep 98) |
| </li> |
| </ul> |
| <h2> |
| <a name="Status"></a>Issue Status</h2> |
| <p><b><a name="New">New</a></b> - The issue has not yet been |
| reviewed by the LWG. Any <b>Proposed Resolution</b> is purely a |
| suggestion from the issue submitter, and should not be construed as |
| the view of LWG.</p> |
| |
| <p><b><a name="Open">Open</a></b> - The LWG has discussed the issue |
| but is not yet ready to move the issue forward. There are several |
| possible reasons for open status:</p> |
| <ul> |
| <li>Consensus may have not yet have been reached as to how to deal |
| with the issue.</li> |
| <li>Informal consensus may have been reached, but the LWG awaits |
| exact <b>Proposed Resolution</b> wording for review.</li> |
| <li>The LWG wishes to consult additional technical experts before |
| proceeding.</li> |
| <li>The issue may require further study.</li> |
| </ul> |
| |
| <p>A <b>Proposed Resolution</b> for an open issue is still not be |
| construed as the view of LWG. Comments on the current state of |
| discussions are often given at the end of open issues in an italic |
| font. Such comments are for information only and should not be given |
| undue importance.</p> |
| |
| <p><b><a name="Dup">Dup</a></b> - The LWG has reached consensus that |
| the issue is a duplicate of another issue, and will not be further |
| dealt with. A <b>Rationale</b> identifies the duplicated issue's |
| issue number. </p> |
| |
| <p><b><a name="NAD">NAD</a></b> - The LWG has reached consensus that |
| the issue is not a defect in the Standard, and the issue is ready to |
| forward to the full committee as a proposed record of response. A |
| <b>Rationale</b> discusses the LWG's reasoning.</p> |
| |
| <p><b><a name="Review">Review</a></b> - Exact wording of a |
| <b>Proposed Resolution</b> is now available for review on an issue |
| for which the LWG previously reached informal consensus.</p> |
| |
| <p><b><a name="Tentatively Ready">Tentatively Ready</a></b> - The issue has |
| been reviewed online, but not in a meeting, and some support has been formed |
| for the proposed resolution. Tentatively Ready issues may be moved to Ready |
| and forwarded to full committee within the same meeting. Unlike Ready issues |
| they will be reviewed in subcommittee prior to forwarding to full committee.</p> |
| |
| <p><b><a name="Ready">Ready</a></b> - The LWG has reached consensus |
| that the issue is a defect in the Standard, the <b>Proposed |
| Resolution</b> is correct, and the issue is ready to forward to the |
| full committee for further action as a Defect Report (DR).</p> |
| |
| <p><b><a name="DR">DR</a></b> - (Defect Report) - The full J16 |
| committee has voted to forward the issue to the Project Editor to be |
| processed as a Potential Defect Report. The Project Editor reviews |
| the issue, and then forwards it to the WG21 Convenor, who returns it |
| to the full committee for final disposition. This issues list |
| accords the status of DR to all these Defect Reports regardless of |
| where they are in that process.</p> |
| |
| <p><b><a name="TC">TC</a></b> - (Technical Corrigenda) - The full |
| WG21 committee has voted to accept the Defect Report's Proposed |
| Resolution as a Technical Corrigenda. Action on this issue is thus |
| complete and no further action is possible under ISO rules.</p> |
| |
| <p><b><a name="WP">WP</a></b> - (Working Paper) - The proposed |
| resolution has not been accepted as a Technical Corrigendum, but |
| the full WG21 committee has voted to apply the Defect Report's Proposed |
| Resolution to the working paper.</p> |
| |
| <p><b><a name="RR">RR</a></b> - (Record of Response) - The full WG21 |
| committee has determined that this issue is not a defect in the |
| Standard. Action on this issue is thus complete and no further |
| action is possible under ISO rules.</p> |
| |
| <p><b><a name="Future">Future</a></b> - In addition to the regular |
| status, the LWG believes that this issue should be revisited at the |
| next revision of the standard. It is usually paired with NAD.</p> |
| |
| <p>Issues are always given the status of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> when |
| they first appear on the issues list. They may progress to |
| <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 |
| is actively working on them. When the LWG has reached consensus on |
| the disposition of an issue, the status will then change to |
| <a href="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 |
| forward Ready issues to the Project Editor, they are given the |
| 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 |
| become the basis for Technical Corrigenda (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a>), |
| or are closed without action other than a Record of Response |
| (<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 |
| only issues which are truly defects in the Standard move to the |
| formal ISO DR status. |
| </p> |
| |
| <h2>Active Issues</h2> |
| <hr> |
| <a name="23"><h3>23. 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> |
| <p>The current description of numeric input does not account for the |
| possibility of overflow. This is an implicit result of changing the |
| description to rely on the definition of scanf() (which fails to |
| report overflow), and conflicts with the documented behavior of |
| traditional and current implementations. </p> |
| |
| <p>Users expect, when reading a character sequence that results in a |
| value unrepresentable in the specified type, to have an error |
| reported. The standard as written does not permit this. </p> |
| |
| <p><b>Further comments from Dietmar:</b></p> |
| |
| <p> |
| I don't feel comfortable with the proposed resolution to issue 23: It |
| kind of simplifies the issue to much. Here is what is going on: |
| </p> |
| |
| <p> |
| Currently, the behavior of numeric overflow is rather counter intuitive |
| and hard to trace, so I will describe it briefly: |
| </p> |
| |
| <ul> |
| <li> |
| According to 22.2.2.1.2 <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> |
| paragraph 11 <tt>failbit</tt> is set if <tt>scanf()</tt> would |
| return an input error; otherwise a value is converted to the rules |
| of <tt>scanf</tt>. |
| </li> |
| <li> |
| <tt>scanf()</tt> is defined in terms of <tt>fscanf()</tt>. |
| </li> |
| <li> |
| <tt>fscanf()</tt> returns an input failure if during conversion no |
| character matching the conversion specification could be extracted |
| before reaching EOF. This is the only reason for <tt>fscanf()</tt> |
| to fail due to an input error and clearly does not apply to the case |
| of overflow. |
| </li> |
| <li> |
| Thus, the conversion is performed according to the rules of |
| <tt>fscanf()</tt> which basically says that <tt>strtod</tt>, |
| <tt>strtol()</tt>, etc. are to be used for the conversion. |
| </li> |
| <li> |
| The <tt>strtod()</tt>, <tt>strtol()</tt>, etc. functions consume as |
| many matching characters as there are and on overflow continue to |
| consume matching characters but also return a value identical to |
| the maximum (or minimum for signed types if there was a leading minus) |
| value of the corresponding type and set <tt>errno</tt> to <tt>ERANGE</tt>. |
| </li> |
| <li> |
| Thus, according to the current wording in the standard, overflows |
| can be detected! All what is to be done is to check <tt>errno</tt> |
| after reading an element and, of course, clearing <tt>errno</tt> |
| before trying a conversion. With the current wording, it can be |
| detected whether the overflow was due to a positive or negative |
| number for signed types. |
| </li> |
| </ul> |
| |
| <p><b>Further discussion from Redmond:</b></p> |
| |
| <p>The basic problem is that we've defined our behavior, |
| including our error-reporting behavior, in terms of C90. However, |
| C90's method of reporting overflow in scanf is not technically an |
| "input error". The <tt>strto_*</tt> functions are more precise.</p> |
| |
| <p>There was general consensus that <tt>failbit</tt> should be set |
| upon overflow. We considered three options based on this:</p> |
| <ol> |
| <li>Set failbit upon conversion error (including overflow), and |
| don't store any value.</li> |
| <li>Set failbit upon conversion error, and also set <tt>errno</tt> to |
| indicated the precise nature of the error.</li> |
| <li>Set failbit upon conversion error. If the error was due to |
| overflow, store +-numeric_limits<T>::max() as an |
| overflow indication.</li> |
| </ol> |
| |
| <p>Straw poll: (1) 5; (2) 0; (3) 8.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Discussed at Lillehammer. General outline of what we want the |
| solution to look like: we want to say that overflow is an error, and |
| provide a way to distinguish overflow from other kinds of errors. |
| Choose candidate field the same way scanf does, but don't describe |
| the rest of the process in terms of format. If a finite input field |
| is too large (positive or negative) to be represented as a finite |
| value, then set failbit and assign the nearest representable value. |
| Bill will provide wording.</p> |
| |
| <hr> |
| <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"> [lib.vector]</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> |
| <p><tt>vector<bool></tt> is not a container as its reference and |
| pointer types are not references and pointers. </p> |
| |
| <p>Also it forces everyone to have a space optimization instead of a |
| speed one.</p> |
| |
| <p><b>See also:</b> 99-0008 == N1185 Vector<bool> is |
| Nonconforming, Forces Optimization Choice.</p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[In Santa Cruz the LWG felt that this was Not A Defect.]</i></p> |
| |
| <p><i>[In Dublin many present felt that failure to meet Container |
| requirements was a defect. There was disagreement as to whether |
| or not the optimization requirements constituted a defect.]</i></p> |
| |
| <p><i>[The LWG looked at the following resolutions in some detail: |
| <br> |
| * Not A Defect.<br> |
| * Add a note explaining that vector<bool> does not meet |
| Container requirements.<br> |
| * Remove vector<bool>.<br> |
| * Add a new category of container requirements which |
| vector<bool> would meet.<br> |
| * Rename vector<bool>.<br> |
| <br> |
| No alternative had strong, wide-spread, support and every alternative |
| had at least one "over my dead body" response.<br> |
| <br> |
| There was also mention of a transition scheme something like (1) add |
| vector_bool and deprecate vector<bool> in the next standard. (2) |
| Remove vector<bool> in the following standard.]</i></p> |
| |
| <p><i>[Modifying container requirements to permit returning proxies |
| (thus allowing container requirements conforming vector<bool>) |
| was also discussed.]</i></p> |
| |
| <p><i>[It was also noted that there is a partial but ugly workaround in |
| that vector<bool> may be further specialized with a customer |
| allocator.]</i></p> |
| |
| <p><i>[Kona: Herb Sutter presented his paper J16/99-0035==WG21/N1211, |
| vector<bool>: More Problems, Better Solutions. Much discussion |
| of a two step approach: a) deprecate, b) provide replacement under a |
| new name. LWG straw vote on that: 1-favor, 11-could live with, 2-over |
| my dead body. This resolution was mentioned in the LWG report to the |
| full committee, where several additional committee members indicated |
| over-my-dead-body positions.]</i></p> |
| |
| <p>Discussed at Lillehammer. General agreement that we should |
| deprecate vector<bool> and introduce this functionality under |
| a different name, e.g. bit_vector. This might make it possible to |
| remove the vector<bool> specialization in the standard that comes |
| after C++0x. There was also a suggestion that |
| in C++0x we could additional say that it's implementation defined |
| whether vector<bool> refers to the specialization or to the |
| primary template, but there wasn't general agreement that this was a |
| good idea.</p> |
| |
| <p>We need a paper for the new bit_vector class.</p> |
| |
| <hr> |
| <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> |
| <p> |
| In some places in this section, the terms "fundamental types" and |
| "scalar types" are used when the term "arithmetic types" is intended. |
| The current usage is incorrect because void is a fundamental type and |
| pointers are scalar types, neither of which should have |
| specializations of numeric_limits. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Lillehammer: it remains true that numeric_limits is using |
| imprecise language. However, none of the proposals for changed |
| wording are clearer. A redesign of numeric_limits is needed, but this |
| is more a task than an open issue.]</i></p> |
| <hr> |
| <a name="206"></a><h3><a name="206">206. operator new(size_t, nothrow) may become unlinked to ordinary operator new if ordinary version replaced</a></h3><p><b>Section:</b> 18.5.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete.single"> [lib.new.delete.single]</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> 29 Aug 1999</p> |
| <p>As specified, the implementation of the nothrow version of operator |
| new does not necessarily call the ordinary operator new, but may |
| instead simply call the same underlying allocator and return a null |
| pointer instead of throwing an exception in case of failure.</p> |
| |
| <p>Such an implementation breaks code that replaces the ordinary |
| version of new, but not the nothrow version. If the ordinary version |
| of new/delete is replaced, and if the replaced delete is not |
| compatible with pointers returned from the library versions of new, |
| then when the replaced delete receives a pointer allocated by the |
| library new(nothrow), crash follows.</p> |
| |
| <p>The fix appears to be that the lib version of new(nothrow) must |
| call the ordinary new. Thus when the ordinary new gets replaced, the |
| lib version will call the replaced ordinary new and things will |
| continue to work.</p> |
| |
| <p>An alternative would be to have the ordinary new call |
| new(nothrow). This seems sub-optimal to me as the ordinary version of |
| new is the version most commonly replaced in practice. So one would |
| still need to replace both ordinary and nothrow versions if one wanted |
| to replace the ordinary version.</p> |
| |
| <p>Another alternative is to put in clear text that if one version is |
| replaced, then the other must also be replaced to maintain |
| compatibility. Then the proposed resolution below would just be a |
| quality of implementation issue. There is already such text in |
| paragraph 7 (under the new(nothrow) version). But this nuance is |
| easily missed if one reads only the paragraphs relating to the |
| ordinary new.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><b>Rationale:</b></p> |
| <p>Yes, they may become unlinked, and that is by design. If a user |
| replaces one, the user should also replace the other.</p> |
| |
| <p><i>[ |
| Reopened due to a gcc conversation between Howard, Martin and Gaby. Forwarding |
| or not is visible behavior to the client and it would be useful for the client |
| to know which behavior it could depend on. |
| ]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| If <tt>mm</tt> is a multimap and <tt>p</tt> is an iterator |
| into the multimap, then <tt>mm.insert(p, x)</tt> inserts |
| <tt>x</tt> into <tt>mm</tt> with <tt>p</tt> as a hint as |
| to where it should go. Table 69 claims that the execution time is |
| amortized constant if the insert winds up taking place adjacent to |
| <tt>p</tt>, but does not say when, if ever, this is guaranteed to |
| happen. All it says it that <tt>p</tt> is a hint as to where to |
| insert. |
| </p> |
| <p> |
| The question is whether there is any guarantee about the relationship |
| between <tt>p</tt> and the insertion point, and, if so, what it |
| is. |
| </p> |
| <p> |
| I believe the present state is that there is no guarantee: The user |
| can supply <tt>p</tt>, and the implementation is allowed to |
| disregard it entirely. |
| </p> |
| |
| <p><b>Additional comments from Nathan:</b><br> |
| |
| The vote [in Redmond] was on whether to elaborately specify the use of |
| the hint, or to require behavior only if the value could be inserted |
| adjacent to the hint. I would like to ensure that we have a chance to |
| vote for a deterministic treatment: "before, if possible, otherwise |
| after, otherwise anywhere appropriate", as an alternative to the |
| proposed "before or after, if possible, otherwise [...]". |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <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>, |
| change</p> |
| |
| <blockquote> |
| iterator p is a hint pointing to where the insert |
| should start to search. |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| insertion adjacent to iterator p is preferred if |
| more than one insertion point is valid. |
| </blockquote> |
| |
| <p>and change</p> |
| |
| <blockquote> |
| logarithmic in general, but amortized constant if |
| t is inserted right after p. |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| logarithmic in general, but amortized constant if |
| t is inserted adjacent to iterator p. |
| </blockquote> |
| |
| <p><i>[Toronto: there was general agreement that this is a real defect: |
| when inserting an element x into a multiset that already contains |
| several copies of x, there is no way to know whether the hint will be |
| used. The proposed resolution was that the new element should always |
| be inserted as close to the hint as possible. So, for example, if |
| there is a subsequence of equivalent values, then providing a.begin() |
| as the hint means that the new element should be inserted before the |
| subsequence even if a.begin() is far away. JC van Winkel supplied |
| precise wording for this proposed resolution, and also for an |
| alternative resolution in which hints are only used when they are |
| adjacent to the insertion point.]</i></p> |
| |
| <p><i>[Copenhagen: the LWG agreed to the original proposed resolution, |
| in which an insertion hint would be used even when it is far from the |
| insertion point. This was contingent on seeing a reference |
| implementation showing that it is possible to implement this |
| requirement without loss of efficiency. John Potter provided such a |
| reference implementation.]</i></p> |
| |
| <p><i>[Redmond: The LWG was reluctant to adopt the proposal that |
| emerged from Copenhagen: it seemed excessively complicated, and went |
| beyond fixing the defect that we identified in Toronto. PJP provided |
| the new wording described in this issue. Nathan agrees that we |
| shouldn't adopt the more detailed semantics, and notes: "we know that |
| you can do it efficiently enough with a red-black tree, but there are |
| other (perhaps better) balanced tree techniques that might differ |
| enough to make the detailed semantics hard to satisfy."]</i></p> |
| |
| <p><i>[Curaçao: Nathan should give us the alternative wording he |
| suggests so the LWG can decide between the two options.]</i></p> |
| |
| <p><i>[Lillehammer: The LWG previously rejected the more detailed |
| semantics, because it seemed more loike a new feature than like |
| defect fixing. We're now more sympathetic to it, but we (especially |
| Bill) are still worried about performance. N1780 describes a naive |
| algorithm, but it's not clear whether there is a non-naive |
| implementation. Is it possible to implement this as efficently as |
| the current version of insert?]</i></p> |
| |
| <p><i>[Post Lillehammer: N1780 updated in post meeting mailing with |
| feedback from Lillehammer with more information regarding performance. |
| ]</i></p> |
| |
| <hr> |
| <a name="254"><h3>254. Exception types in clause 19 are constructed from <tt>std::string</tt> |
| </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> |
| <p> |
| Many of the standard exception types which implementations are |
| required to throw are constructed with a const std::string& |
| parameter. For example: |
| </p> |
| |
| <pre> 19.1.5 Class out_of_range [lib.out.of.range] |
| namespace std { |
| class out_of_range : public logic_error { |
| public: |
| explicit out_of_range(const string& what_arg); |
| }; |
| } |
| |
| 1 The class out_of_range defines the type of objects thrown as excep- |
| tions to report an argument value not in its expected range. |
| |
| out_of_range(const string& what_arg); |
| |
| Effects: |
| Constructs an object of class out_of_range. |
| Postcondition: |
| strcmp(what(), what_arg.c_str()) == 0. |
| </pre> |
| |
| <p> |
| There are at least two problems with this: |
| </p> |
| <ol> |
| <li>A program which is low on memory may end up throwing |
| std::bad_alloc instead of out_of_range because memory runs out while |
| constructing the exception object.</li> |
| <li>An obvious implementation which stores a std::string data member |
| may end up invoking terminate() during exception unwinding because the |
| exception object allocates memory (or rather fails to) as it is being |
| copied.</li> |
| </ol> |
| |
| <p> |
| There may be no cure for (1) other than changing the interface to |
| out_of_range, though one could reasonably argue that (1) is not a |
| defect. Personally I don't care that much if out-of-memory is reported |
| when I only have 20 bytes left, in the case when out_of_range would |
| have been reported. People who use exception-specifications might care |
| a lot, though. |
| </p> |
| |
| <p> |
| There is a cure for (2), but it isn't completely obvious. I think a |
| note for implementors should be made in the standard. Avoiding |
| possible termination in this case shouldn't be left up to chance. The |
| cure is to use a reference-counted "string" implementation |
| in the exception object. I am not necessarily referring to a |
| std::string here; any simple reference-counting scheme for a NTBS |
| would do. |
| </p> |
| |
| <p><b>Further discussion, in email:</b></p> |
| |
| <p> |
| ...I'm not so concerned about (1). After all, a library implementation |
| can add const char* constructors as an extension, and users don't |
| <i>need</i> to avail themselves of the standard exceptions, though this is |
| a lame position to be forced into. FWIW, std::exception and |
| std::bad_alloc don't require a temporary basic_string. |
| </p> |
| |
| <p> |
| ...I don't think the fixed-size buffer is a solution to the problem, |
| strictly speaking, because you can't satisfy the postcondition |
| <br> |
| <tt> strcmp(what(), what_arg.c_str()) == 0</tt> |
| <br> |
| For all values of what_arg (i.e. very long values). That means that |
| the only truly conforming solution requires a dynamic allocation. |
| </p> |
| |
| <p><b>Further discussion, from Redmond:</b></p> |
| |
| <p>The most important progress we made at the Redmond meeting was |
| realizing that there are two separable issues here: the const |
| string& constructor, and the copy constructor. If a user writes |
| something like <tt>throw std::out_of_range("foo")</tt>, the const |
| string& constructor is invoked before anything gets thrown. The |
| copy constructor is potentially invoked during stack unwinding.</p> |
| |
| <p>The copy constructor is a more serious problem, becuase failure |
| during stack unwinding invokes <tt>terminate</tt>. The copy |
| constructor must be nothrow. <i>Curaçao: Howard thinks this |
| requirement may already be present.</i></p> |
| |
| <p>The fundamental problem is that it's difficult to get the nothrow |
| requirement to work well with the requirement that the exception |
| objects store a string of unbounded size, particularly if you also try |
| to make the const string& constructor nothrow. Options discussed |
| include:</p> |
| |
| <ul> |
| <li>Limit the size of a string that exception objects are required to |
| 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 |
| 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: |
| "strncmp(what(), what_arg._str(), N) == 0, where N is an |
| implementation defined constant no smaller than 256".</li> |
| <li>Allow the const string& constructor to throw, but not the |
| copy constructor. It's the implementor's responsibility to get it |
| right. (An implementor might use a simple refcount class.)</li> |
| <li>Compromise between the two: an implementation is not allowed to |
| throw if the string's length is less than some N, but, if it doesn't |
| throw, the string must compare equal to the argument.</li> |
| <li>Add a new constructor that takes a const char*</li> |
| </ul> |
| |
| <p>(Not all of these options are mutually exclusive.)</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><b>Rationale:</b></p> |
| |
| <p>Throwing a bad_alloc while trying to construct a message for another |
| exception-derived class is not necessarily a bad thing. And the |
| bad_alloc constructor already has a no throw spec on it (18.4.2.1).</p> |
| |
| <p><b>Future:</b></p> |
| |
| <p>All involved would like to see const char* constructors added, but |
| this should probably be done for C++0X as opposed to a DR.</p> |
| |
| <p>I believe the no throw specs currently decorating these functions |
| could be improved by some kind of static no throw spec checking |
| mechanism (in a future C++ language). As they stand, the copy |
| constructors might fail via a call to unexpected. I think what is |
| intended here is that the copy constructors can't fail.</p> |
| |
| <p><i>[Pre-Sydney: reopened at the request of Howard Hinnant. |
| Post-Redmond: James Kanze noticed that the copy constructors of |
| exception-derived classes do not have nothrow clauses. Those |
| classes have no copy constructors declared, meaning the |
| compiler-generated implicit copy constructors are used, and those |
| compiler-generated constructors might in principle throw anything.]</i></p> |
| |
| <hr> |
| <a name="255"><h3>255. Why do <tt>basic_streambuf<>::pbump()</tt> and <tt>gbump()</tt> take an int?</h3></a><p><b>Section:</b> 27.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf"> [lib.streambuf]</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> 12 Aug 2000</p> |
| <p> |
| The basic_streambuf members gbump() and pbump() are specified to take an |
| int argument. This requirement prevents the functions from effectively |
| manipulating buffers larger than std::numeric_limits<int>::max() |
| characters. It also makes the common use case for these functions |
| somewhat difficult as many compilers will issue a warning when an |
| argument of type larger than int (such as ptrdiff_t on LLP64 |
| architectures) is passed to either of the function. Since it's often the |
| result of the subtraction of two pointers that is passed to the |
| functions, a cast is necessary to silence such warnings. Finally, the |
| usage of a native type in the functions signatures is inconsistent with |
| other member functions (such as sgetn() and sputn()) that manipulate the |
| underlying character buffer. Those functions take a streamsize argument. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the signatures of these functions in the synopsis of template |
| class basic_streambuf (27.5.2) and in their descriptions (27.5.2.3.1, p4 |
| and 27.5.2.3.2, p4) to take a streamsize argument. |
| </p> |
| |
| <p> |
| Although this change has the potential of changing the ABI of the |
| library, the change will affect only platforms where int is different |
| than the definition of streamsize. However, since both functions are |
| typically inline (they are on all known implementations), even on such |
| platforms the change will not affect any user code unless it explicitly |
| relies on the existing type of the functions (e.g., by taking their |
| address). Such a possibility is IMO quite remote. |
| </p> |
| |
| <p> |
| Alternate Suggestion from Howard Hinnant, c++std-lib-7780: |
| </p> |
| |
| <p> |
| This is something of a nit, but I'm wondering if streamoff wouldn't be a |
| better choice than streamsize. The argument to pbump and gbump MUST be |
| signed. But the standard has this to say about streamsize |
| (27.4.1/2/Footnote): |
| </p> |
| |
| <blockquote> |
| [Footnote: streamsize is used in most places where ISO C would use |
| size_t. Most of the uses of streamsize could use size_t, except for |
| the strstreambuf constructors, which require negative values. It |
| should probably be the signed type corresponding to size_t (which is |
| what Posix.2 calls ssize_t). --- end footnote] |
| </blockquote> |
| |
| <p> |
| This seems a little weak for the argument to pbump and gbump. Should we |
| ever really get rid of strstream, this footnote might go with it, along |
| with the reason to make streamsize signed. |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes this change is too big for now. We may wish to |
| reconsider this for a future revision of the standard. One |
| possibility is overloading pbump, rather than changing the |
| signature.</p> |
| <p><i>[ |
| [2006-05-04: Reopened at the request of Chris (Krzysztof ?elechowski)] |
| ]</i></p> |
| <hr> |
| <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.default.con.req"> [lib.default.con.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> Matt Austern <b>Date:</b> 22 Aug 2000</p> |
| <p> |
| From lib-7752: |
| </p> |
| |
| <p> |
| I've been assuming (and probably everyone else has been assuming) that |
| allocator instances have a particular property, and I don't think that |
| property can be deduced from anything in Table 32. |
| </p> |
| |
| <p> |
| I think we have to assume that allocator type conversion is a |
| homomorphism. That is, if x1 and x2 are of type X, where |
| X::value_type is T, and if type Y is X::template |
| rebind<U>::other, then Y(x1) == Y(x2) if and only if x1 == x2. |
| </p> |
| |
| <p> |
| Further discussion: Howard Hinnant writes, in lib-7757: |
| </p> |
| |
| <p> |
| I think I can prove that this is not provable by Table 32. And I agree |
| it needs to be true except for the "and only if". If x1 != x2, I see no |
| reason why it can't be true that Y(x1) == Y(x2). Admittedly I can't |
| think of a practical instance where this would happen, or be valuable. |
| But I also don't see a need to add that extra restriction. I think we |
| only need: |
| </p> |
| |
| <blockquote> |
| if (x1 == x2) then Y(x1) == Y(x2) |
| </blockquote> |
| |
| <p> |
| If we decide that == on allocators is transitive, then I think I can |
| prove the above. But I don't think == is necessarily transitive on |
| allocators. That is: |
| </p> |
| |
| <p> |
| Given x1 == x2 and x2 == x3, this does not mean x1 == x3. |
| </p> |
| |
| <p>Example:</p> |
| |
| <blockquote> |
| <p> |
| x1 can deallocate pointers from: x1, x2, x3 <br> |
| x2 can deallocate pointers from: x1, x2, x4 <br> |
| x3 can deallocate pointers from: x1, x3 <br> |
| x4 can deallocate pointers from: x2, x4 |
| </p> |
| |
| <p> |
| x1 == x2, and x2 == x4, but x1 != x4 |
| </p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Toronto: LWG members offered multiple opinions. One |
| opinion is that it should not be required that <tt>x1 == x2</tt> |
| implies <tt>Y(x1) == Y(x2)</tt>, and that it should not even be |
| required that <tt>X(x1) == x1</tt>. Another opinion is that |
| the second line from the bottom in table 32 already implies the |
| desired property. This issue should be considered in light of |
| other issues related to allocator instances.]</i></p> |
| <hr> |
| <a name="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> |
| <p>The specification of the for_each algorithm does not have a |
| "Requires" section, which means that there are no |
| restrictions imposed on the function object whatsoever. In essence it |
| means that I can provide any function object with arbitrary side |
| effects and I can still expect a predictable result. In particular I |
| can expect that the function object is applied exactly last - first |
| times, which is promised in the "Complexity" section. |
| </p> |
| |
| <p>I don't see how any implementation can give such a guarantee |
| without imposing requirements on the function object. |
| </p> |
| |
| <p>Just as an example: consider a function object that removes |
| elements from the input sequence. In that case, what does the |
| complexity guarantee (applies f exactly last - first times) mean? |
| </p> |
| |
| <p>One can argue that this is obviously a nonsensical application and |
| a theoretical case, which unfortunately it isn't. I have seen |
| programmers shooting themselves in the foot this way, and they did not |
| understand that there are restrictions even if the description of the |
| algorithm does not say so. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Lillehammer: This is more general than for_each. We don't want |
| the function object in transform invalidiating iterators |
| either. There should be a note somewhere in clause 17 (17, not 25) |
| saying that user code operating on a range may not invalidate |
| iterators unless otherwise specified. Bill will provide wording.]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| 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>, |
| Table 75 gives the return type of *r-- as convertible to T. This is |
| not consistent with Table 74 which gives the return type of *r++ as |
| T&. *r++ = t is valid while *r-- = t is invalid. |
| </p> |
| |
| <p> |
| 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>, |
| Table 76 gives the return type of a[n] as convertible to T. This is |
| not consistent with the semantics of *(a + n) which returns T& by |
| Table 74. *(a + n) = t is valid while a[n] = t is invalid. |
| </p> |
| |
| <p> |
| Discussion from the Copenhagen meeting: the first part is |
| uncontroversial. The second part, operator[] for Random Access |
| Iterators, requires more thought. There are reasonable arguments on |
| both sides. Return by value from operator[] enables some potentially |
| useful iterators, e.g. a random access "iota iterator" (a.k.a |
| "counting iterator" or "int iterator"). There isn't any obvious way |
| to do this with return-by-reference, since the reference would be to a |
| temporary. On the other hand, <tt>reverse_iterator</tt> takes an |
| arbitrary Random Access Iterator as template argument, and its |
| operator[] returns by reference. If we decided that the return type |
| in Table 76 was correct, we would have to change |
| <tt>reverse_iterator</tt>. This change would probably affect user |
| code. |
| </p> |
| |
| <p> |
| History: the contradiction between <tt>reverse_iterator</tt> and the |
| Random Access Iterator requirements has been present from an early |
| stage. In both the STL proposal adopted by the committee |
| (N0527==94-0140) and the STL technical report (HPL-95-11 (R.1), by |
| Stepanov and Lee), the Random Access Iterator requirements say that |
| operator[]'s return value is "convertible to T". In N0527 |
| reverse_iterator's operator[] returns by value, but in HPL-95-11 |
| (R.1), and in the STL implementation that HP released to the public, |
| reverse_iterator's operator[] returns by reference. In 1995, the |
| standard was amended to reflect the contents of HPL-95-11 (R.1). The |
| original intent for operator[] is unclear. |
| </p> |
| |
| <p> |
| In the long term it may be desirable to add more fine-grained |
| iterator requirements, so that access method and traversal strategy |
| can be decoupled. (See "Improved Iterator Categories and |
| Requirements", N1297 = 01-0011, by Jeremy Siek.) Any decisions |
| about issue 299 should keep this possibility in mind. |
| </p> |
| |
| <p>Further discussion: I propose a compromise between John Potter's |
| resolution, which requires <tt>T&</tt> as the return type of |
| <tt>a[n]</tt>, and the current wording, which requires convertible to |
| <tt>T</tt>. The compromise is to keep the convertible to <tt>T</tt> |
| for the return type of the expression <tt>a[n]</tt>, but to also add |
| <tt>a[n] = t</tt> as a valid expression. This compromise "saves" the |
| common case uses of random access iterators, while at the same time |
| allowing iterators such as counting iterator and caching file |
| iterators to remain random access iterators (iterators where the |
| lifetime of the object returned by <tt>operator*()</tt> is tied to the |
| lifetime of the iterator). |
| </p> |
| |
| <p> |
| Note that the compromise resolution necessitates a change to |
| <tt>reverse_iterator</tt>. It would need to use a proxy to support |
| <tt>a[n] = t</tt>. |
| </p> |
| |
| <p> |
| Note also there is one kind of mutable random access iterator that |
| will no longer meet the new requirements. Currently, iterators that |
| return an r-value from <tt>operator[]</tt> meet the requirements for a |
| mutable random access iterartor, even though the expression <tt>a[n] = |
| t</tt> will only modify a temporary that goes away. With this proposed |
| resolution, <tt>a[n] = t</tt> will be required to have the same |
| operational semantics as <tt>*(a + n) = t</tt>. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| In section 24.1.4 [lib.bidirectdional.iterators], change the return |
| type in table 75 from "convertible to <tt>T</tt>" to |
| <tt>T&</tt>. |
| </p> |
| |
| <p> |
| In section 24.1.5 [lib.random.access.iterators], change the |
| operational semantics for <tt>a[n]</tt> to " the r-value of |
| <tt>a[n]</tt> is equivalent to the r-value of <tt>*(a + |
| n)</tt>". Add a new row in the table for the expression <tt>a[n] = t</tt> |
| with a return type of convertible to <tt>T</tt> and operational semantics of |
| <tt>*(a + n) = t</tt>. |
| </p> |
| |
| <p><i>[Lillehammer: Real problem, but should be addressed as part of |
| iterator redesign]</i></p> |
| |
| <hr> |
| <a name="309"><h3>309. Does sentry catch exceptions?</h3></a><p><b>Section:</b> 27.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.format"> [lib.iostream.format]</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> 19 Mar 2001</p> |
| <p> |
| The descriptions of the constructors of basic_istream<>::sentry |
| (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>) and basic_ostream<>::sentry |
| (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>) do not explain what the functions do in |
| case an exception is thrown while they execute. Some current |
| implementations allow all exceptions to propagate, others catch them |
| and set ios_base::badbit instead, still others catch some but let |
| others propagate. |
| </p> |
| |
| <p> |
| The text also mentions that the functions may call setstate(failbit) |
| (without actually saying on what object, but presumably the stream |
| argument is meant). That may have been fine for |
| basic_istream<>::sentry prior to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#195">195</a>, since |
| the function performs an input operation which may fail. However, |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#195">195</a> amends 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>, p2 to |
| clarify that the function should actually call setstate(failbit | |
| eofbit), so the sentence in p3 is redundant or even somewhat |
| contradictory. |
| </p> |
| |
| <p> |
| The same sentence that appears in 27.6.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream::sentry"> [lib.ostream::sentry]</a>, p3 |
| doesn't seem to be very meaningful for basic_istream<>::sentry |
| which performs no input. It is actually rather misleading since it |
| would appear to guide library implementers to calling |
| setstate(failbit) when os.tie()->flush(), the only called function, |
| throws an exception (typically, it's badbit that's set in response to |
| such an event). |
| </p> |
| |
| <p><b>Additional comments from Martin, who isn't comfortable with the |
| current proposed resolution</b> (see c++std-lib-11530)</p> |
| |
| <p> |
| The istream::sentry ctor says nothing about how the function |
| deals with exemptions (27.6.1.1.2, p1 says that the class is |
| responsible for doing "exception safe"(*) prefix and suffix |
| operations but it doesn't explain what level of exception |
| safety the class promises to provide). The mockup example |
| of a "typical implementation of the sentry ctor" given in |
| 27.6.1.1.2, p6, removed in ISO/IEC 14882:2003, doesn't show |
| exception handling, either. Since the ctor is not classified |
| as a formatted or unformatted input function, the text in |
| 27.6.1.1, p1 through p4 does not apply. All this would seem |
| to suggest that the sentry ctor should not catch or in any |
| way handle exceptions thrown from any functions it may call. |
| Thus, the typical implementation of an istream extractor may |
| look something like [1]. |
| </p> |
| |
| <p> |
| The problem with [1] is that while it correctly sets ios::badbit |
| if an exception is thrown from one of the functions called from |
| the sentry ctor, if the sentry ctor reaches EOF while extracting |
| whitespace from a stream that has eofbit or failbit set in |
| exceptions(), it will cause an ios::failure to be thrown, which |
| will in turn cause the extractor to set ios::badbit. |
| </p> |
| |
| <p> |
| The only straightforward way to prevent this behavior is to |
| move the definition of the sentry object in the extractor |
| above the try block (as suggested by the example in 22.2.8, |
| p9 and also indirectly supported by 27.6.1.3, p1). See [2]. |
| But such an implementation will allow exceptions thrown from |
| functions called from the ctor to freely propagate to the |
| caller regardless of the setting of ios::badbit in the stream |
| object's exceptions(). |
| </p> |
| |
| <p> |
| So since neither [1] nor [2] behaves as expected, the only |
| possible solution is to have the sentry ctor catch exceptions |
| thrown from called functions, set badbit, and propagate those |
| exceptions if badbit is also set in exceptions(). (Another |
| solution exists that deals with both kinds of sentries, but |
| the code is non-obvious and cumbersome -- see [3].) |
| </p> |
| |
| <p> |
| Please note that, as the issue points out, current libraries |
| do not behave consistently, suggesting that implementors are |
| not quite clear on the exception handling in istream::sentry, |
| despite the fact that some LWG members might feel otherwise. |
| (As documented by the parenthetical comment here: |
| http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1480.html#309) |
| </p> |
| |
| <p> |
| Also please note that those LWG members who in Copenhagen |
| felt that "a sentry's constructor should not catch exceptions, |
| because sentries should only be used within (un)formatted input |
| functions and that exception handling is the responsibility of |
| those functions, not of the sentries," as noted here |
| http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1310.html#309 |
| would in effect be either arguing for the behavior described |
| in [1] or for extractors implemented along the lines of [3]. |
| </p> |
| |
| <p> |
| The original proposed resolution (Revision 25 of the issues |
| list) clarifies the role of the sentry ctor WRT exception |
| handling by making it clear that extractors (both library |
| or user-defined) should be implemented along the lines of |
| [2] (as opposed to [1]) and that no exception thrown from |
| the callees should propagate out of either function unless |
| badbit is also set in exceptions(). |
| </p> |
| |
| |
| <p>[1] Extractor that catches exceptions thrown from sentry:</p> |
| |
| <blockquote> |
| <pre>struct S { long i; }; |
| |
| istream& operator>> (istream &strm, S &s) |
| { |
| ios::iostate err = ios::goodbit; |
| try { |
| const istream::sentry guard (strm, false); |
| if (guard) { |
| use_facet<num_get<char> >(strm.getloc ()) |
| .get (istreambuf_iterator<char>(strm), |
| istreambuf_iterator<char>(), |
| strm, err, s.i); |
| } |
| } |
| catch (...) { |
| bool rethrow; |
| try { |
| strm.setstate (ios::badbit); |
| rethrow = false; |
| } |
| catch (...) { |
| rethrow = true; |
| } |
| if (rethrow) |
| throw; |
| } |
| if (err) |
| strm.setstate (err); |
| return strm; |
| } |
| </pre> |
| </blockquote> |
| |
| <p>[2] Extractor that propagates exceptions thrown from sentry:</p> |
| |
| <blockquote> |
| <pre>istream& operator>> (istream &strm, S &s) |
| { |
| istream::sentry guard (strm, false); |
| if (guard) { |
| ios::iostate err = ios::goodbit; |
| try { |
| use_facet<num_get<char> >(strm.getloc ()) |
| .get (istreambuf_iterator<char>(strm), |
| istreambuf_iterator<char>(), |
| strm, err, s.i); |
| } |
| catch (...) { |
| bool rethrow; |
| try { |
| strm.setstate (ios::badbit); |
| rethrow = false; |
| } |
| catch (...) { |
| rethrow = true; |
| } |
| if (rethrow) |
| throw; |
| } |
| if (err) |
| strm.setstate (err); |
| } |
| return strm; |
| } |
| </pre> |
| </blockquote> |
| |
| <p> |
| [3] Extractor that catches exceptions thrown from sentry |
| but doesn't set badbit if the exception was thrown as a |
| result of a call to strm.clear(). |
| </p> |
| |
| <blockquote> |
| <pre>istream& operator>> (istream &strm, S &s) |
| { |
| const ios::iostate state = strm.rdstate (); |
| const ios::iostate except = strm.exceptions (); |
| ios::iostate err = std::ios::goodbit; |
| bool thrown = true; |
| try { |
| const istream::sentry guard (strm, false); |
| thrown = false; |
| if (guard) { |
| use_facet<num_get<char> >(strm.getloc ()) |
| .get (istreambuf_iterator<char>(strm), |
| istreambuf_iterator<char>(), |
| strm, err, s.i); |
| } |
| } |
| catch (...) { |
| if (thrown && state & except) |
| throw; |
| try { |
| strm.setstate (ios::badbit); |
| thrown = false; |
| } |
| catch (...) { |
| thrown = true; |
| } |
| if (thrown) |
| throw; |
| } |
| if (err) |
| strm.setstate (err); |
| |
| return strm; |
| } |
| </pre> |
| </blockquote> |
| |
| <p> |
| [Pre-Berlin] Reopened at the request of Paolo Carlini and Steve Clamage. |
| </p> |
| |
| <p> |
| [Pre-Portland] A relevant newsgroup post: |
| </p> |
| |
| <p> |
| The current proposed resolution of issue #309 |
| (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#309) is |
| unacceptable. I write commerical software and coding around this |
| makes my code ugly, non-intuitive, and requires comments referring |
| people to this very issue. Following is the full explanation of my |
| experience. |
| </p> |
| <p> |
| In the course of writing software for commercial use, I constructed |
| std::ifstream's based on user-supplied pathnames on typical POSIX |
| systems. |
| </p> |
| <p> |
| It was expected that some files that opened successfully might not read |
| successfully -- such as a pathname which actually refered to a |
| directory. Intuitively, I expected the streambuffer underflow() code |
| to throw an exception in this situation, and recent implementations of |
| libstdc++'s basic_filebuf do just that (as well as many of my own |
| custom streambufs). |
| </p> |
| <p> |
| I also intuitively expected that the istream code would convert these |
| exceptions to the "badbit' set on the stream object, because I had not |
| requested exceptions. I refer to 27.6.1.1. P4. |
| </p> |
| <p> |
| However, this was not the case on at least two implementations -- if |
| the first thing I did with an istream was call operator>>( T& ) for T |
| among the basic arithmetic types and std::string. Looking further I |
| found that the sentry's constructor was invoking the exception when it |
| pre-scanned for whitespace, and the extractor function (operator>>()) |
| was not catching exceptions in this situation. |
| </p> |
| <p> |
| So, I was in a situation where setting 'noskipws' would change the |
| istream's behavior even though no characters (whitespace or not) could |
| ever be successfully read. |
| </p> |
| <p> |
| Also, calling .peek() on the istream before calling the extractor() |
| changed the behavior (.peek() had the effect of setting the badbit |
| ahead of time). |
| </p> |
| <p> |
| I found this all to be so inconsistent and inconvenient for me and my |
| code design, that I filed a bugzilla entry for libstdc++. I was then |
| told that the bug cannot be fixed until issue #309 is resolved by the |
| committee. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG agrees there is minor variation between implementations, |
| but believes that it doesn't matter. This is a rarely used corner |
| case. There is no evidence that this has any commercial importance |
| or that it causes actual portability problems for customers trying |
| to write code that runs on multiple implementations.</p> |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 09 Oct 2001</p> |
| <p>I think we have a defect.</p> |
| |
| <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 |
| 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 |
| like:</p> |
| |
| <blockquote> |
| Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1), except that it does not count the number of characters |
| extracted and does not affect the value returned by subsequent calls to |
| gcount(). After constructing a sentry object, if fail() != true, |
| executes rdbuf()Â>pubseekpos( pos). |
| </blockquote> |
| |
| <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, |
| 27.6.1.3, paragraph 1 looks like:</p> |
| |
| <blockquote> |
| Each unformatted input function begins execution by constructing an |
| object of class sentry with the default argument noskipws (second) |
| argument true. If the sentry object returns true, when converted to a |
| value of type bool, the function endeavors to obtain the requested |
| input. Otherwise, if the sentry constructor exits by throwing an |
| exception or if the sentry object returns false, when converted to a |
| value of type bool, the function returns without attempting to obtain |
| any input. In either case the number of extracted characters is set to |
| 0; unformatted input functions taking a character array of non-zero |
| size as an argument shall also store a null character (using charT()) |
| in the first location of the array. If an exception is thrown during |
| input then ios::badbit is turned on in *this'ss error state. If |
| (exception()&badbit)!= 0 then the exception is rethrown. It also counts |
| the number of characters extracted. If no exception has been thrown it |
| ends by storing the count in a member object and returning the value |
| specified. In any event the sentry object is destroyed before leaving |
| the unformatted input function. |
| </blockquote> |
| |
| <p>And finally 27.6.1.1.2/5 says this about sentry:</p> |
| |
| <blockquote> |
| If, after any preparation is completed, is.good() is true, ok_ != false |
| otherwise, ok_ == false. |
| </blockquote> |
| |
| <p> |
| So although the seekg paragraph says that the operation proceeds if |
| !fail(), the behavior of unformatted functions says the operation |
| proceeds only if good(). The two statements are contradictory when only |
| eofbit is set. I don't think the current text is clear which condition |
| should be respected. |
| </p> |
| |
| <p><b>Further discussion from Redmond:</b></p> |
| |
| <p>PJP: It doesn't seem quite right to say that <tt>seekg</tt> is |
| "unformatted". That makes specific claims about sentry that |
| aren't quite appropriate for seeking, which has less fragile failure |
| modes than actual input. If we do really mean that it's unformatted |
| input, it should behave the same way as other unformatted input. On |
| the other hand, "principle of least surprise" is that seeking from EOF |
| ought to be OK.</p> |
| |
| <p> |
| Pre-Berlin: Paolo points out several problems with the proposed resolution in |
| Ready state: |
| </p> |
| |
| <ul> |
| <li>It should apply to both overloads of seekg.</li> |
| <li>tellg has similar issues, except that it should not call clear().</li> |
| <li>The point about clear() seems to apply to seekp().</li> |
| <li>Depending on the outcome of |
| <a href="file:///Volumes/Data/lwg/lwg-active.html#419">419</a> if the sentry |
| sets <tt>failbit</tt> when it finds <tt>eofbit</tt> already set, then |
| you can never seek away from the end of stream.</li> |
| </ul> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <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> |
| <blockquote> |
| Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1), except that it does not count the number of characters |
| extracted, does not affect the value returned by subsequent calls to |
| gcount(), and does not examine the value returned by the sentry |
| object. After constructing a sentry object, if <tt>fail() != |
| true</tt>, executes <tt>rdbuf()->pubseekpos(pos)</tt>. In |
| case of success, the function calls clear(). |
| In case of failure, the function calls <tt>setstate(failbit)</tt> |
| (which may throw <tt>ios_base::failure</tt>). |
| </blockquote> |
| |
| <p><i>[Lillehammer: Matt provided wording.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>In C, fseek does clear EOF. This is probably what most users would |
| expect. We agree that having eofbit set should not deter a seek, |
| and that a successful seek should clear eofbit. Note |
| that <tt>fail()</tt> is true only if <tt>failbit</tt> |
| or <tt>badbit</tt> is set, so using <tt>!fail()</tt>, rather |
| than <tt>good()</tt>, satisfies this goal.</p> |
| <hr> |
| <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.byname"> [lib.locale.codecvt.byname]</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> |
| <p> |
| It seems that the descriptions of codecvt do_in() and do_out() leave |
| sufficient room for interpretation so that two implementations of |
| codecvt may not work correctly with the same filebuf. Specifically, |
| the following seems less than adequately specified: |
| </p> |
| |
| <ol> |
| <li> |
| the conditions under which the functions terminate |
| </li> |
| <li> |
| precisely when the functions return ok |
| </li> |
| <li> |
| precisely when the functions return partial |
| </li> |
| <li> |
| the full set of conditions when the functions return error |
| </li> |
| </ol> |
| |
| <ol> |
| <li> |
| <font color="red">22.2.1.5.2</font>, p2 says this about the effects of the |
| function: ...Stops if it encounters a character it cannot |
| convert... This assumes that there *is* a character to |
| convert. What happens when there is a sequence that doesn't form a |
| valid source character, such as an unassigned or invalid UNICODE |
| character, or a sequence that cannot possibly form a character |
| (e.g., the sequence "\xc0\xff" in UTF-8)? |
| </li> |
| <li> |
| Table 53 says that the function returns codecvt_base::ok |
| to indicate that the function(s) "completed the conversion." |
| Suppose that the source sequence is "\xc0\x80" in UTF-8, |
| with from pointing to '\xc0' and (from_end==from + 1). |
| It is not clear whether the return value should be ok |
| or partial (see below). |
| </li> |
| <li> |
| Table 53 says that the function returns codecvt_base::partial |
| if "not all source characters converted." With the from pointers |
| set up the same way as above, it is not clear whether the return |
| value should be partial or ok (see above). |
| </li> |
| <li> |
| Table 53, in the row describing the meaning of error mistakenly |
| refers to a "from_type" character, without the symbol from_type |
| having been defined. Most likely, the word "source" character |
| is intended, although that is not sufficient. The functions |
| may also fail when they encounter an invalid source sequence |
| that cannot possibly form a valid source character (e.g., as |
| explained in bullet 1 above). |
| </li> |
| </ol> |
| <p> |
| Finally, the conditions described at the end of <font color="red">22.2.1.5.2</font>, p4 don't seem to be possible: |
| </p> |
| <blockquote> |
| "A return value of partial, if (from_next == from_end), |
| indicates that either the destination sequence has not |
| absorbed all the available destination elements, or that |
| additional source elements are needed before another |
| destination element can be produced." |
| </blockquote> |
| <p> |
| If the value is partial, it's not clear to me that (from_next |
| ==from_end) could ever hold if there isn't enough room |
| in the destination buffer. In order for (from_next==from_end) to |
| hold, all characters in that range must have been successfully |
| converted (according to <font color="red">22.2.1.5.2</font>, p2) and since there are no |
| further source characters to convert, no more room in the |
| destination buffer can be needed. |
| </p> |
| <p> |
| It's also not clear to me that (from_next==from_end) could ever |
| hold if additional source elements are needed to produce another |
| destination character (not element as incorrectly stated in the |
| text). partial is returned if "not all source characters have |
| been converted" according to Table 53, which also implies that |
| (from_next==from) does NOT hold. |
| </p> |
| <p> |
| Could it be that the intended qualifying condition was actually |
| (from_next != from_end), i.e., that the sentence was supposed |
| to read |
| </p> |
| <blockquote> |
| "A return value of partial, if (from_next != from_end),..." |
| </blockquote> |
| <p> |
| which would make perfect sense, since, as far as I understand it, |
| partial can only occur if (from_next != from_end)? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Lillehammer: Defer for the moment, but this really needs to be |
| fixed. Right now, the description of codecvt is too vague for it to |
| be a useful contract between providers and clients of codecvt |
| facets. (Note that both vendors and users can be both providers and |
| clients of codecvt facets.) The major philosophical issue is whether |
| the standard should only describe mappings that take a single wide |
| character to multiple narrow characters (and vice versa), or whether |
| it should describe fully general N-to-M conversions. When the |
| original standard was written only the former was contemplated, but |
| today, in light of the popularity of utf8 and utf16, that doesn't |
| seem sufficient for C++0x. Bill supports general N-to-M conversions; |
| we need to make sure Martin and Howard agree.]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| Many function templates have parameters that are passed by value; |
| a typical example is <tt>find_if</tt>'s <i>pred</i> parameter in |
| 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 |
| (<tt>Predicate</tt> in this case) implicitly required to be |
| CopyConstructible, or does that need to be spelled out explicitly? |
| </p> |
| |
| <p> |
| This isn't quite as silly a question as it might seem to be at first |
| sight. If you call <tt>find_if</tt> in such a way that template |
| argument deduction applies, then of course you'll get call by value |
| and you need to provide a copy constructor. If you explicitly provide |
| the template arguments, however, you can force call by reference by |
| writing something like <tt>find_if<my_iterator, |
| my_predicate&></tt>. The question is whether implementation |
| are required to accept this, or whether this is ill-formed because |
| my_predicate& is not CopyConstructible. |
| </p> |
| |
| <p> |
| The scope of this problem, if it is a problem, is unknown. Function |
| 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> |
| 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 |
| library is necessary. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[ |
| This is really two issues. First, predicates are typically passed by |
| value but we don't say they must be Copy Constructible. They should |
| be. Second: is specialization allowed to transform value arguments |
| into references? References aren't copy constructible, so this should |
| not be allowed. |
| ]</i></p> |
| <hr> |
| <a name="387"><h3>387. std::complex over-encapsulated</h3></a><p><b>Section:</b> 26.3 <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> |
| <p> |
| The absence of explicit description of std::complex<T> layout |
| makes it imposible to reuse existing software developed in traditional |
| languages like Fortran or C with unambigous and commonly accepted |
| layout assumptions. There ought to be a way for practitioners to |
| predict with confidence the layout of std::complex<T> whenever T |
| is a numerical datatype. The absence of ways to access individual |
| parts of a std::complex<T> object as lvalues unduly promotes |
| severe pessimizations. For example, the only way to change, |
| independently, the real and imaginary parts is to write something like |
| </p> |
| |
| <pre>complex<T> z; |
| // ... |
| // set the real part to r |
| z = complex<T>(r, z.imag()); |
| // ... |
| // set the imaginary part to i |
| z = complex<T>(z.real(), i); |
| </pre> |
| |
| <p> |
| At this point, it seems appropriate to recall that a complex number |
| is, in effect, just a pair of numbers with no particular invariant to |
| maintain. Existing practice in numerical computations has it that a |
| complex number datatype is usually represented by Cartesian |
| coordinates. Therefore the over-encapsulation put in the specification |
| of std::complex<> is not justified. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following requirements to 26.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.numbers"> [lib.complex.numbers]</a> as 26.3/4:</p> |
| <blockquote> |
| <p>If z is an lvalue expression of type cv std::complex<T> then</p> |
| |
| <ul> |
| <li>the expression reinterpret_cast<cv T(&)[2]>(z) |
| is well-formed; and</li> |
| <li>reinterpret_cast<cvT(&)[2]>(z)[0]designates the |
| real part of z; and</li> |
| <li>reinterpret_cast<cvT(&)[2]>(z)[1]designates the |
| imaginary part of z.</li> |
| </ul> |
| |
| <p> |
| Moreover, if a is an expression of pointer type cv complex<T>* |
| and the expression a[i] is well-defined for an integer expression |
| i then: |
| </p> |
| |
| <ul> |
| <li>reinterpret_cast<cvT*>(a)[2+i] designates the real |
| part of a[i]; and</li> |
| <li>reinterpret_cast<cv T*>(a)[2+i+1] designates the |
| imaginary part of a[i].</li> |
| </ul> |
| </blockquote> |
| |
| <p>In the header synopsis in 26.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.synopsis"> [lib.complex.synopsis]</a>, replace</p> |
| <pre> template<class T> T real(const complex<T>&); |
| template<class T> T imag(const complex<T>&); |
| </pre> |
| |
| <p>with</p> |
| |
| <pre> template<class T> const T& real(const complex<T>&); |
| template<class T> T& real( complex<T>&); |
| template<class T> const T& imag(const complex<T>&); |
| template<class T> T& imag( complex<T>&); |
| </pre> |
| |
| <p>In 26.3.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> |
| <pre> template<class T> T real(const complex<T>&); |
| </pre> |
| <p>to</p> |
| <pre> template<class T> const T& real(const complex<T>&); |
| template<class T> T& real( complex<T>&); |
| </pre> |
| <p>and change the <b>Returns</b> clause to "<b>Returns:</b> The real |
| part of <i>x</i></p>. |
| |
| <p>In 26.3.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> |
| <pre> template<class T> T imag(const complex<T>&); |
| </pre> |
| <p>to</p> |
| <pre> template<class T> const T& imag(const complex<T>&); |
| template<class T> T& imag( complex<T>&); |
| </pre> |
| <p>and change the <b>Returns</b> clause to "<b>Returns:</b> The imaginary |
| part of <i>x</i></p>. |
| |
| <p><i>[Kona: The layout guarantee is absolutely necessary for C |
| compatibility. However, there was disagreement about the other part |
| of this proposal: retrieving elements of the complex number as |
| lvalues. An alternative: continue to have real() and imag() return |
| rvalues, but add set_real() and set_imag(). Straw poll: return |
| lvalues - 2, add setter functions - 5. Related issue: do we want |
| reinterpret_cast as the interface for converting a complex to an |
| array of two reals, or do we want to provide a more explicit way of |
| doing it? Howard will try to resolve this issue for the next |
| meeting.]</i></p> |
| |
| <p><i>[pre-Sydney: Howard summarized the options in n1589.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes that C99 compatibility would be enough |
| justification for this change even without other considerations. All |
| existing implementations already have the layout proposed here.</p> |
| <hr> |
| <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> |
| <p> |
| There is a contradiction in Formatted output about what bit is |
| supposed to be set if the formatting fails. On sentence says it's |
| badbit and another that it's failbit. |
| </p> |
| <p> |
| 27.6.2.5.1, p1 says in the Common Requirements on Formatted output |
| functions: |
| </p><pre> ... If the generation fails, then the formatted output function |
| does setstate(ios::failbit), which might throw an exception. |
| </pre> |
| <p></p> |
| <p> |
| 27.6.2.5.2, p1 goes on to say this about Arithmetic Inserters: |
| </p> |
| <p> |
| ... The formatting conversion occurs as if it performed the |
| following code fragment: |
| </p> |
| <p> |
| </p><pre> bool failed = |
| use_facet<num_put<charT,ostreambuf_iterator<charT,traits> |
| > > |
| (getloc()).put(*this, *this, fill(), val). failed(); |
| |
| ... If failed is true then does setstate(badbit) ... |
| </pre> |
| <p></p> |
| <p> |
| The original intent of the text, according to Jerry Schwarz (see |
| c++std-lib-10500), is captured in the following paragraph: |
| </p> |
| <p> |
| In general "badbit" should mean that the stream is unusable because |
| of some underlying failure, such as disk full or socket closure; |
| "failbit" should mean that the requested formatting wasn't possible |
| because of some inconsistency such as negative widths. So typically |
| if you clear badbit and try to output something else you'll fail |
| again, but if you clear failbit and try to output something else |
| you'll succeed. |
| </p> |
| <p> |
| In the case of the arithmetic inserters, since num_put cannot |
| report failure by any means other than exceptions (in response |
| to which the stream must set badbit, which prevents the kind of |
| recoverable error reporting mentioned above), the only other |
| detectable failure is if the iterator returned from num_put |
| returns true from failed(). |
| </p> |
| <p> |
| Since that can only happen (at least with the required iostream |
| specializations) under such conditions as the underlying failure |
| referred to above (e.g., disk full), setting badbit would seem |
| to be the appropriate response (indeed, it is required in |
| 27.6.2.5.2, p1). It follows that failbit can never be directly |
| set by the arithmetic (it can only be set by the sentry object |
| under some unspecified conditions). |
| </p> |
| <p> |
| The situation is different for other formatted output functions |
| which can fail as a result of the streambuf functions failing |
| (they may do so by means other than exceptions), and which are |
| then required to set failbit. |
| </p> |
| <p> |
| The contradiction, then, is that ostream::operator<<(int) will |
| set badbit if the disk is full, while operator<<(ostream&, |
| char) will set failbit under the same conditions. To make the behavior |
| consistent, the Common requirements sections for the Formatted output |
| functions should be changed as proposed below. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| |
| <p><i>[Kona: There's agreement that this is a real issue. What we |
| decided at Kona: 1. An error from the buffer (which can be detected |
| either directly from streambuf's member functions or by examining a |
| streambuf_iterator) should always result in badbit getting set. |
| 2. There should never be a circumstance where failbit gets set. |
| That represents a formatting error, and there are no circumstances |
| under which the output facets are specified as signaling a |
| formatting error. (Even more so for string output that for numeric |
| because there's nothing to format.) If we ever decide to make it |
| possible for formatting errors to exist then the facets can signal |
| the error directly, and that should go in clause 22, not clause 27. |
| 3. The phrase "if generation fails" is unclear and should be |
| eliminated. It's not clear whether it's intended to mean a buffer |
| error (e.g. a full disk), a formatting error, or something else. |
| Most people thought it was supposed to refer to buffer errors; if |
| so, we should say so. Martin will provide wording.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| |
| <hr> |
| <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> |
| <p> |
| 23.3.5.1, p6 [lib.bitset.cons] talks about a generic character |
| having the value of 0 or 1 but there is no definition of what |
| that means for charT other than char and wchar_t. And even for |
| those two types, the values 0 and 1 are not actually what is |
| intended -- the values '0' and '1' are. This, along with the |
| converse problem in the description of to_string() in 23.3.5.2, |
| p33, looks like a defect remotely related to DR 303. |
| </p> |
| <p> |
| http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#303 |
| </p> |
| <pre>23.3.5.1: |
| -6- An element of the constructed string has value zero if the |
| corresponding character in str, beginning at position pos, |
| is 0. Otherwise, the element has the value one. |
| </pre> |
| <pre>23.3.5.2: |
| -33- Effects: Constructs a string object of the appropriate |
| type and initializes it to a string of length N characters. |
| Each character is determined by the value of its |
| corresponding bit position in *this. Character position N |
| ?- 1 corresponds to bit position zero. Subsequent decreasing |
| character positions correspond to increasing bit positions. |
| Bit value zero becomes the character 0, bit value one becomes |
| the character 1. |
| </pre> |
| <p> |
| Also note the typo in 23.3.5.1, p6: the object under construction |
| is a bitset, not a string. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the constructor's function declaration immediately before |
| 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> |
| <pre> template <class charT, class traits, class Allocator> |
| explicit |
| bitset(const basic_string<charT, traits, Allocator>& str, |
| typename basic_string<charT, traits, Allocator>::size_type pos = 0, |
| typename basic_string<charT, traits, Allocator>::size_type n = |
| basic_string<charT, traits, Allocator>::npos, |
| charT zero = charT('0'), charT one = charT('1')) |
| </pre> |
| <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 |
| element of the constructed string has value 0 if the corresponding |
| character in <i>str</i>, beginning at position <i>pos</i>, |
| is <i>zero</i>. Otherwise, the element has the value 1.</p> |
| |
| <p>Change the text of the second sentence in 23.3.5.1, p5 to read: |
| "The function then throws invalid_argument if any of the rlen |
| characters in str beginning at position pos is other than <i>zero</i> |
| or <i>one</i>. The function uses traits::eq() to compare the character |
| values." |
| </p> |
| |
| <p>Change the declaration of the <tt>to_string</tt> member function |
| 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> |
| <pre> template <class charT, class traits, class Allocator> |
| basic_string<charT, traits, Allocator> |
| to_string(charT zero = charT('0'), charT one = charT('1')) const; |
| </pre> |
| <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 |
| value 0 becomes the character <tt><i>zero</i></tt>, bit value 1 becomes the |
| character <tt><i>one</i></tt>.</p> |
| <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> |
| <p><b>Returns</b>:</p> |
| <pre> os << x.template to_string<charT,traits,allocator<charT> >( |
| use_facet<ctype<charT> >(<i>os</i>.getloc()).widen('0'), |
| use_facet<ctype<charT> >(<i>os</i>.getloc()).widen('1')); |
| </pre> |
| <p><b>Rationale:</b></p> |
| <p>There is a real problem here: we need the character values of '0' |
| and '1', and we have no way to get them since strings don't have |
| imbued locales. In principle the "right" solution would be to |
| provide an extra object, either a ctype facet or a full locale, |
| which would be used to widen '0' and '1'. However, there was some |
| discomfort about using such a heavyweight mechanism. The proposed |
| resolution allows those users who care about this issue to get it |
| right.</p> |
| <p>We fix the inserter to use the new arguments. Note that we already |
| 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> |
| |
| <hr> |
| <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> |
| <p> |
| 17.4.4.8, p3 prohibits library dtors from throwing exceptions. |
| </p> |
| <p> |
| 27.6.2.3, p4 says this about the ostream::sentry dtor: |
| </p> |
| <pre> -4- If ((os.flags() & ios_base::unitbuf) && !uncaught_exception()) |
| is true, calls os.flush(). |
| </pre> |
| <p> |
| 27.6.2.6, p7 that describes ostream::flush() says: |
| </p> |
| <pre> -7- If rdbuf() is not a null pointer, calls rdbuf()->pubsync(). |
| If that function returns ?-1 calls setstate(badbit) (which |
| may throw ios_base::failure (27.4.4.3)). |
| </pre> |
| <p> |
| That seems like a defect, since both pubsync() and setstate() can |
| throw an exception. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[ |
| The contradiction is real. Clause 17 says destructors may never |
| throw exceptions, and clause 27 specifies a destructor that does |
| throw. In principle we might change either one. We're leaning |
| toward changing clause 17: putting in an "unless otherwise specified" |
| clause, and then putting in a footnote saying the sentry destructor |
| is the only one that can throw. PJP suggests specifying that |
| sentry::~sentry() should internally catch any exceptions it might cause. |
| ]</i></p> |
| <hr> |
| <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> |
| <p> |
| While reviewing unformatted input member functions of istream |
| for their behavior when they encounter end-of-file during input |
| I found that the requirements vary, sometimes unexpectedly, and |
| in more than one case even contradict established practice (GNU |
| libstdc++ 3.2, IBM VAC++ 6.0, STLPort 4.5, SunPro 5.3, HP aCC |
| 5.38, Rogue Wave libstd 3.1, and Classic Iostreams). |
| </p> |
| <p> |
| The following unformatted input member functions set eofbit if they |
| encounter an end-of-file (this is the expected behavior, and also |
| the behavior of all major implementations): |
| </p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| get (char_type*, streamsize, char_type); |
| </pre> |
| <p></p> |
| <p> |
| Also sets failbit if it fails to extract any characters. |
| </p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| get (char_type*, streamsize); |
| </pre> |
| <p></p> |
| <p> |
| Also sets failbit if it fails to extract any characters. |
| </p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| getline (char_type*, streamsize, char_type); |
| </pre> |
| <p></p> |
| <p> |
| Also sets failbit if it fails to extract any characters. |
| </p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| getline (char_type*, streamsize); |
| </pre> |
| <p></p> |
| <p> |
| Also sets failbit if it fails to extract any characters. |
| </p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| ignore (int, int_type); |
| </pre> |
| <p></p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| read (char_type*, streamsize); |
| </pre> |
| <p></p> |
| <p> |
| Also sets failbit if it encounters end-of-file. |
| </p> |
| <p> |
| </p><pre> streamsize readsome (char_type*, streamsize); |
| </pre> |
| <p></p> |
| |
| <p> |
| The following unformated input member functions set failbit but |
| not eofbit if they encounter an end-of-file (I find this odd |
| since the functions make it impossible to distinguish a general |
| failure from a failure due to end-of-file; the requirement is |
| also in conflict with all major implementation which set both |
| eofbit and failbit): |
| </p> |
| <p> |
| </p><pre> int_type get(); |
| </pre> |
| <p></p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| get (char_type&); |
| </pre> |
| <p></p> |
| <p> |
| These functions only set failbit of they extract no characters, |
| otherwise they don't set any bits, even on failure (I find this |
| inconsistency quite unexpected; the requirement is also in |
| conflict with all major implementations which set eofbit |
| whenever they encounter end-of-file): |
| </p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| get (basic_streambuf<charT, traits>&, char_type); |
| </pre> |
| <p></p> |
| <p> |
| </p><pre> basic_istream<charT, traits>& |
| get (basic_streambuf<charT, traits>&); |
| </pre> |
| <p></p> |
| <p> |
| This function sets no bits (all implementations except for |
| STLport and Classic Iostreams set eofbit when they encounter |
| end-of-file): |
| </p> |
| <p> |
| </p><pre> int_type peek (); |
| </pre> |
| <p></p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Informally, what we want is a global statement of intent saying |
| that eofbit gets set if we trip across EOF, and then we can take |
| away the specific wording for individual functions. A full review |
| is necessary. The wording currently in the standard is a mishmash, |
| and changing it on an individual basis wouldn't make things better. |
| Dietmar will do this work.</p> |
| <hr> |
| <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.default.con.req"> [lib.default.con.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> Markus Mauhart <b>Date:</b> 27 Feb 2003</p> |
| <p> |
| I think that in par2 of 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.default.con.req"> [lib.default.con.req]</a> the last two |
| lines of table 32 contain two incorrect type casts. The lines are ... |
| </p> |
| |
| <pre> a.construct(p,t) Effect: new((void*)p) T(t) |
| a.destroy(p) Effect: ((T*)p)?->~T() |
| </pre> |
| |
| <p> |
| .... with the prerequisits coming from the preceding two paragraphs, especially |
| from table 31: |
| </p> |
| |
| <pre> alloc<T> a ;// an allocator for T |
| alloc<T>::pointer p ;// random access iterator |
| // (may be different from T*) |
| alloc<T>::reference r = *p;// T& |
| T const& t ; |
| </pre> |
| |
| <p> |
| For that two type casts ("(void*)p" and "(T*)p") to be well-formed |
| this would require then conversions to T* and void* for all |
| alloc<T>::pointer, so it would implicitely introduce extra |
| requirements for alloc<T>::pointer, additionally to the only |
| current requirement (being a random access iterator). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| "(void*)p" should be replaced with "(void*)&*p" and that |
| "((T*)p)?->" should be replaced with "(*p)." or with |
| "(&*p)->". |
| </p> |
| |
| <p> |
| Note: Actually I would prefer to replace "((T*)p)?->dtor_name" with |
| "p?->dtor_name", but AFAICS this is not possible cause of an omission |
| 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). |
| </p> |
| |
| <p><i>[Kona: The LWG thinks this is somewhere on the border between |
| Open and NAD. The intend is clear: <tt>construct</tt> constructs an |
| object at the location <i>p</i>. It's reading too much into the |
| description to think that literally calling <tt>new</tt> is |
| required. Tweaking this description is low priority until we can do |
| a thorough review of allocators, and, in particular, allocators with |
| non-default pointer types.]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| I've been discussing iterator semantics with Dave Abrahams, and a |
| surprise has popped up. I don't think this has been discussed before. |
| </p> |
| |
| <p> |
| 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" |
| iterator values is to assign a non-singular value to them. (It |
| doesn't say they can be destroyed, and that's probably a defect.) |
| Some implementations have taken this to imply that there is no need |
| to initialize the data member of a reverse_iterator<> in the default |
| constructor. As a result, code like |
| </p> |
| <blockquote> |
| std::vector<std::reverse_iterator<char*> > v(7); |
| v.reserve(1000); |
| </blockquote> |
| <p> |
| invokes undefined behavior, because it must default-initialize the |
| vector elements, and then copy them to other storage. Of course many |
| other vector operations on these adapters are also left undefined, |
| and which those are is not reliably deducible from the standard. |
| </p> |
| |
| <p> |
| I don't think that 24.1 was meant to make standard-library iterator |
| types unsafe. Rather, it was meant to restrict what operations may |
| be performed by functions which take general user- and standard |
| iterators as arguments, so that raw pointers would qualify as |
| iterators. However, this is not clear in the text, others have come |
| to the opposite conclusion. |
| </p> |
| |
| <p> |
| One question is whether the standard iterator adaptors have defined |
| copy semantics. Another is whether they have defined destructor |
| semantics: is |
| </p> |
| <blockquote> |
| { std::vector<std::reverse_iterator<char*> > v(7); } |
| </blockquote> |
| <p> |
| undefined too? |
| </p> |
| |
| <p> |
| Note this is not a question of whether algorithms are allowed to |
| rely on copy semantics for arbitrary iterators, just whether the |
| types we actually supply support those operations. I believe the |
| resolution must be expressed in terms of the semantics of the |
| adapter's argument type. It should make clear that, e.g., the |
| reverse_iterator<T> constructor is actually required to execute |
| T(), and so copying is defined if the result of T() is copyable. |
| </p> |
| |
| <p> |
| Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#235">235</a>, which defines reverse_iterator's default |
| constructor more precisely, has some relevance to this issue. |
| However, it is not the whole story. |
| </p> |
| |
| <p> |
| The issue was whether |
| </p> |
| <blockquote> |
| reverse_iterator() { } |
| </blockquote> |
| <p> |
| is allowed, vs. |
| </p> |
| <blockquote> |
| reverse_iterator() : current() { } |
| </blockquote> |
| |
| <p> |
| The difference is when T is char*, where the first leaves the member |
| uninitialized, and possibly equal to an existing pointer value, or |
| (on some targets) may result in a hardware trap when copied. |
| </p> |
| |
| <p> |
| 8.5 paragraph 5 seems to make clear that the second is required to |
| 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 |
| types. |
| </p> |
| |
| <p> |
| But that only takes care of reverse_iterator, and doesn't establish |
| a policy for all iterators. (The reverse iterator adapter was just |
| an example.) In particular, does my function |
| </p> |
| <blockquote> |
| template <typename Iterator> |
| void f() { std::vector<Iterator> v(7); } |
| </blockquote> |
| <p> |
| evoke undefined behavior for some conforming iterator definitions? |
| I think it does, now, because vector<> will destroy those singular |
| iterator values, and that's explicitly disallowed. |
| </p> |
| |
| <p> |
| 24.1 shouldn't give blanket permission to copy all singular iterators, |
| because then pointers wouldn't qualify as iterators. However, it |
| should allow copying of that subset of singular iterator values that |
| are default-initialized, and it should explicitly allow destroying any |
| iterator value, singular or not, default-initialized or not. |
| </p> |
| |
| <p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#407">407</a></p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[ |
| We don't want to require all singular iterators to be copyable, |
| because that is not the case for pointers. However, default |
| construction may be a special case. Issue: is it really default |
| construction we want to talk about, or is it something like value |
| initialization? We need to check with core to see whether default |
| constructed pointers are required to be copyable; if not, it would be |
| wrong to impose so strict a requirement for iterators. |
| ]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| |
| Given two overloads of the function foo(), one taking an argument of type |
| int and the other taking a long, which one will the call foo(LONG_MAX) |
| resolve to? The expected answer should be foo(long), but whether that |
| is true depends on the #defintion of the LONG_MAX macro, specifically |
| its type. This issue is about the fact that the type of these macros |
| is not actually required to be the same as the the type each respective |
| limit. |
| <br> |
| |
| Section 18.2.2 of the C++ Standard does not specify the exact types of |
| the XXX_MIN and XXX_MAX macros #defined in the <climits> and <limits.h> |
| headers such as INT_MAX and LONG_MAX and instead defers to the C standard. |
| <br> |
| |
| Section 5.2.4.2.1, p1 of the C standard specifies that "The values [of |
| these constants] shall be replaced by constant expressions suitable for use |
| in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, |
| the following shall be replaced by expressions that have the same type as |
| would an expression that is an object of the corresponding type converted |
| according to the integer promotions." |
| <br> |
| |
| The "corresponding type converted according to the integer promotions" for |
| LONG_MAX is, according to 6.4.4.1, p5 of the C standard, the type of long |
| converted to the first of the following set of types that can represent it: |
| int, long int, long long int. So on an implementation where (sizeof(long) |
| == sizeof(int)) this type is actually int, while on an implementation where |
| (sizeof(long) > sizeof(int)) holds this type will be long. |
| <br> |
| |
| This is not an issue in C since the type of the macro cannot be detected |
| by any conforming C program, but it presents a portability problem in C++ |
| where the actual type is easily detectable by overload resolution. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Kona: the LWG does not believe this is a defect. The C macro |
| definitions are what they are; we've got a better |
| mechanism, <tt>std::numeric_limits</tt>, that is specified more |
| precisely than the C limit macros. At most we should add a |
| nonnormative note recommending that users who care about the exact |
| types of limit quantities should use <limits> instead of |
| <climits>.]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| The Effects and Returns clauses of the do_widen() member function of |
| the ctype facet fail to specify the behavior of the function on failure. |
| That the function may not be able to simply cast the narrow character |
| argument to the type of the result since doing so may yield the wrong value |
| for some wchar_t encodings. Popular implementations of ctype<wchar_t> that |
| use mbtowc() and UTF-8 as the native encoding (e.g., GNU glibc) will fail |
| when the argument's MSB is set. There is no way for the the rest of locale |
| and iostream to reliably detect this failure. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Kona: This is a real problem. Widening can fail. It's unclear |
| what the solution should be. Returning WEOF works for the wchar_t |
| specialization, but not in general. One option might be to add a |
| default, like <i>narrow</i>. But that's an incompatible change. |
| Using <i>traits::eof</i> might seem like a good idea, but facets |
| don't have access to traits (a recurring problem). We could |
| have <i>widen</i> throw an exception, but that's a scary option; |
| existing library components aren't written with the assumption |
| that <i>widen</i> can throw.]</i></p> |
| <hr> |
| <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> |
| <p> |
| The dtor of the ios_base::Init object is supposed to call flush() on the |
| 6 standard iostream objects cout, cerr, clog, wcout, wcerr, and wclog. |
| This call may cause an exception to be thrown. |
| </p> |
| |
| <p> |
| 17.4.4.8, p3 prohibits all library destructors from throwing exceptions. |
| </p> |
| |
| <p> |
| The question is: What should this dtor do if one or more of these calls |
| to flush() ends up throwing an exception? This can happen quite easily |
| if one of the facets installed in the locale imbued in the iostream |
| object throws. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Kona: We probably can't do much better than what we've got, so |
| the LWG is leaning toward NAD. At the point where the standard |
| stream objects are being cleaned up, the usual error reporting |
| mechanism are all unavailable. And exception from flush at this |
| point will definitely cause problems. A quality implementation |
| might reasonably swallow the exception, or call abort, or do |
| something even more drastic.]</i></p> |
| <hr> |
| <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> |
| <p> |
| |
| 27.6.1.1.2, p2 says that istream::sentry ctor prepares for input if is.good() |
| is true. p4 then goes on to say that the ctor sets the sentry::ok_ member to |
| true if the stream state is good after any preparation. 27.6.1.2.1, p1 then |
| says that a formatted input function endeavors to obtain the requested input |
| if the sentry's operator bool() returns true. |
| |
| Given these requirements, no formatted extractor should ever set failbit if |
| the initial stream rdstate() == eofbit. That is contrary to the behavior of |
| all implementations I tested. The program below prints out |
| |
| eof = 1, fail = 0 |
| eof = 1, fail = 1 |
| |
| on all of them. |
| </p> |
| <pre> |
| #include <sstream> |
| #include <cstdio> |
| |
| int main() |
| { |
| std::istringstream strm ("1"); |
| |
| int i = 0; |
| |
| strm >> i; |
| |
| std::printf ("eof = %d, fail = %d\n", |
| !!strm.eof (), !!strm.fail ()); |
| |
| strm >> i; |
| |
| std::printf ("eof = %d, fail = %d\n", |
| !!strm.eof (), !!strm.fail ()); |
| } |
| |
| </pre> |
| <p> |
| <br> |
| |
| Comments from Jerry Schwarz (c++std-lib-11373): |
| <br> |
| |
| Jerry Schwarz wrote: |
| <br> |
| |
| I don't know where (if anywhere) it says it in the standard, but the |
| formatted extractors are supposed to set failbit if they don't extract |
| any characters. If they didn't then simple loops like |
| <br> |
| |
| while (cin >> x); |
| <br> |
| |
| would loop forever. |
| <br> |
| |
| Further comments from Martin Sebor: |
| <br> |
| |
| The question is which part of the extraction should prevent this from happening |
| by setting failbit when eofbit is already set. It could either be the sentry |
| object or the extractor. It seems that most implementations have chosen to |
| set failbit in the sentry [...] so that's the text that will need to be |
| corrected. |
| |
| </p> |
| <p> |
| Pre Berlin: This issue is related to |
| <a href="file:///Volumes/Data/lwg/lwg-active.html#342">342</a>. If the sentry |
| sets <tt>failbit</tt> when it finds <tt>eofbit</tt> already set, then |
| you can never seek away from the end of stream. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Kona: Possibly NAD. If eofbit is set then good() will return false. We |
| then set <i>ok</i> to false. We believe that the sentry's |
| constructor should always set failbit when <i>ok</i> is false, and |
| we also think the standard already says that. Possibly it could be |
| clearer.</p> |
| |
| <hr> |
| <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> |
| <p> |
| The reflector thread starting with c++std-lib-11346 notes that the class |
| template basic_streambuf, along with basic_stringbuf and basic_filebuf, |
| is copy-constructible but that the semantics of the copy constructors |
| are not defined anywhere. Further, different implementations behave |
| differently in this respect: some prevent copy construction of objects |
| of these types by declaring their copy ctors and assignment operators |
| private, others exhibit undefined behavior, while others still give |
| these operations well-defined semantics. |
| </p> |
| |
| <p> |
| Note that this problem doesn't seem to be isolated to just the three |
| types mentioned above. A number of other types in the library section |
| of the standard provide a compiler-generated copy ctor and assignment |
| operator yet fail to specify their semantics. It's believed that the |
| only types for which this is actually a problem (i.e. types where the |
| compiler-generated default may be inappropriate and may not have been |
| intended) are locale facets. See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#439">439</a>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 27.5.2 [lib.streambuf]: Add into the synopsis, public section, just above the destructor declaration: |
| </p> |
| |
| <blockquote> |
| <pre>basic_streambuf(const basic_streambuf& sb); |
| basic_streambuf& operator=(const basic_streambuf& sb); |
| </pre> |
| </blockquote> |
| |
| <p>Insert after 27.5.2.1, paragraph 2:</p> |
| <blockquote> |
| <pre>basic_streambuf(const basic_streambuf& sb); |
| </pre> |
| |
| <p>Constructs a copy of sb.</p> |
| <p>Postcondtions:</p> |
| <pre> eback() == sb.eback() |
| gptr() == sb.gptr() |
| egptr() == sb.egptr() |
| pbase() == sb.pbase() |
| pptr() == sb.pptr() |
| epptr() == sb.epptr() |
| getloc() == sb.getloc() |
| </pre> |
| |
| <pre>basic_streambuf& operator=(const basic_streambuf& sb); |
| </pre> |
| |
| <p>Assigns the data members of sb to this.</p> |
| |
| <p>Postcondtions:</p> |
| <pre> eback() == sb.eback() |
| gptr() == sb.gptr() |
| egptr() == sb.egptr() |
| pbase() == sb.pbase() |
| pptr() == sb.pptr() |
| epptr() == sb.epptr() |
| getloc() == sb.getloc() |
| </pre> |
| |
| <p>Returns: *this.</p> |
| </blockquote> |
| |
| <p>27.7.1 [lib.stringbuf]:</p> |
| |
| <b>Option A:</b> |
| |
| <blockquote> |
| <p>Insert into the basic_stringbuf synopsis in the private section:</p> |
| |
| <pre>basic_stringbuf(const basic_stringbuf&); // not defined |
| basic_stringbuf& operator=(const basic_stringbuf&); // not defined |
| </pre> |
| </blockquote> |
| |
| <b>Option B:</b> |
| |
| <blockquote> |
| <p>Insert into the basic_stringbuf synopsis in the public section:</p> |
| |
| <pre>basic_stringbuf(const basic_stringbuf& sb); |
| basic_stringbuf& operator=(const basic_stringbuf& sb); |
| </pre> |
| |
| <p>27.7.1.1, insert after paragraph 4:</p> |
| |
| <pre>basic_stringbuf(const basic_stringbuf& sb);</pre> |
| |
| <p> |
| Constructs an independent copy of sb as if with sb.str(), and with the openmode that sb was constructed with. |
| </p> |
| |
| <p>Postcondtions: </p> |
| <pre> str() == sb.str() |
| gptr() - eback() == sb.gptr() - sb.eback() |
| egptr() - eback() == sb.egptr() - sb.eback() |
| pptr() - pbase() == sb.pptr() - sb.pbase() |
| getloc() == sb.getloc() |
| </pre> |
| |
| <p> |
| Note: The only requirement on epptr() is that it point beyond the |
| initialized range if an output sequence exists. There is no requirement |
| that epptr() - pbase() == sb.epptr() - sb.pbase(). |
| </p> |
| |
| <pre>basic_stringbuf& operator=(const basic_stringbuf& sb);</pre> |
| <p>After assignment the basic_stringbuf has the same state as if it |
| were initially copy constructed from sb, except that the |
| basic_stringbuf is allowed to retain any excess capacity it might have, |
| which may in turn effect the value of epptr(). |
| </p> |
| </blockquote> |
| |
| <p>27.8.1.1 [lib.filebuf]</p> |
| |
| <p>Insert at the bottom of the basic_filebuf synopsis:</p> |
| |
| <blockquote> |
| <pre>private: |
| basic_filebuf(const basic_filebuf&); // not defined |
| basic_filebuf& operator=(const basic_filebuf&); // not defined |
| </pre> |
| </blockquote> |
| <p><i>[Kona: this is an issue for basic_streambuf itself and for its |
| derived classes. We are leaning toward allowing basic_streambuf to |
| be copyable, and specifying its precise semantics. (Probably the |
| obvious: copying the buffer pointers.) We are less sure whether |
| the streambuf derived classes should be copyable. Howard will |
| write up a proposal.]</i></p> |
| |
| <p><i>[Sydney: Dietmar presented a new argument against basic_streambuf |
| being copyable: it can lead to an encapsulation violation. Filebuf |
| inherits from streambuf. Now suppose you inhert a my_hijacking_buf |
| from streambuf. You can copy the streambuf portion of a filebuf to a |
| my_hijacking_buf, giving you access to the pointers into the |
| filebuf's internal buffer. Perhaps not a very strong argument, but |
| it was strong enough to make people nervous. There was weak |
| preference for having streambuf not be copyable. There was weak |
| preference for having stringbuf not be copyable even if streambuf |
| is. Move this issue to open for now. |
| ]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| 27.5.2 [lib.streambuf]: The proposed basic_streambuf copy constructor |
| and assignment operator are the same as currently implied by the lack |
| of declarations: public and simply copies the data members. This |
| resolution is not a change but a clarification of the current |
| standard. |
| </p> |
| |
| <p> |
| 27.7.1 [lib.stringbuf]: There are two reasonable options: A) Make |
| basic_stringbuf not copyable. This is likely the status-quo of |
| current implementations. B) Reasonable copy semantics of |
| basic_stringbuf can be defined and implemented. A copyable |
| basic_streambuf is arguably more useful than a non-copyable one. This |
| should be considered as new functionality and not the fixing of a |
| defect. If option B is chosen, ramifications from issue 432 are taken |
| into account. |
| </p> |
| |
| <p> |
| 27.8.1.1 [lib.filebuf]: There are no reasonable copy semantics for |
| basic_filebuf. |
| </p> |
| |
| <hr> |
| <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> |
| <p> |
| It has been suggested that 17.4.3.1, p1 may or may not allow programs to |
| explicitly specialize members of standard templates on user-defined types. |
| The answer to the question might have an impact where library requirements |
| are given using the "as if" rule. I.e., if programs are allowed to specialize |
| member functions they will be able to detect an implementation's strict |
| conformance to Effects clauses that describe the behavior of the function |
| in terms of the other member function (the one explicitly specialized by |
| the program) by relying on the "as if" rule. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| 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: |
| </p> |
| |
| <blockquote> |
| The behavior of a program that declares explicit specializations |
| of any members of class templates or explicit specializations of |
| any member templates of classes or class templates defined in |
| this library is undefined. |
| </blockquote> |
| |
| |
| <p><i>[Kona: straw poll was 6-1 that user programs should not be |
| allowed to specialize individual member functions of standard |
| library class templates, and that doing so invokes undefined |
| behavior. Post-Kona: Martin provided wording.]</i></p> |
| |
| <p><i>[Sydney: The LWG agrees that the standard shouldn't permit users |
| to specialize individual member functions unless they specialize the |
| whole class, but we're not sure these words say what we want them to; |
| they could be read as prohibiting the specialization of any standard |
| library class templates. We need to consult with CWG to make sure we |
| use the right wording.]</i></p> |
| |
| <hr> |
| <a name="423"></a><h3><a name="423">423. effects of negative streamsize in iostreams</a></h3><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> |
| |
| <p> |
| A third party test suite tries to exercise istream::ignore(N) with |
| a negative value of N and expects that the implementation will treat |
| N as if it were 0. Our implementation asserts that (N >= 0) holds and |
| aborts the test. |
| </p> |
| |
| <p> |
| I can't find anything in section 27 that prohibits such values but I don't |
| see what the effects of such calls should be, either (this applies to |
| a number of unformatted input functions as well as some member functions |
| of the basic_streambuf template). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| I propose that we add to each function in clause 27 that takes an argument, |
| say N, of type streamsize a Requires clause saying that "N >= 0." The intent |
| is to allow negative streamsize values in calls to precision() and width() |
| but disallow it in calls to streambuf::sgetn(), istream::ignore(), or |
| ostream::write(). |
| </p> |
| |
| <p><i>[Kona: The LWG agreed that this is probably what we want. However, we |
| need a review to find all places where functions in clause 27 take |
| arguments of type streamsize that shouldn't be allowed to go |
| negative. Martin will do that review.]</i></p> |
| |
| <hr> |
| <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> |
| |
| <p> |
| The text in 17.3.1.1, p1 says: |
| <br> |
| |
| "Paragraphs labelled "Note(s):" or "Example(s):" are informative, other |
| paragraphs are normative." |
| <br> |
| |
| The library section makes heavy use of paragraphs labeled "Notes(s)," |
| some of which are clearly intended to be normative (see list 1), while |
| some others are not (see list 2). There are also those where the intent |
| is not so clear (see list 3). |
| <br> |
| |
| List 1 -- Examples of (presumably) normative Notes: |
| <br> |
| |
| 20.4.1.1, p3, 20.4.1.1, p10, 21.3.1, p11, 22.1.1.2, p11, 23.2.1.3, p2, |
| 25.3.7, p3, 26.2.6, p14a, 27.5.2.4.3, p7. |
| <br> |
| |
| List 2 -- Examples of (presumably) informative Notes: |
| <br> |
| |
| 18.4.1.3, p3, 21.3.5.6, p14, 22.2.1.5.2, p3, 25.1.1, p4, 26.2.5, p1, |
| 27.4.2.5, p6. |
| <br> |
| |
| List 3 -- Examples of Notes that are not clearly either normative |
| or informative: |
| <br> |
| |
| 22.1.1.2, p8, 22.1.1.5, p6, 27.5.2.4.5, p4. |
| <br> |
| |
| None of these lists is meant to be exhaustive. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Definitely a real problem. The big problem is there's material |
| that doesn't quite fit any of the named paragraph categories |
| (e.g. <b>Effects</b>). Either we need a new kind of named |
| paragraph, or we need to put more material in unnamed paragraphs |
| jsut after the signature. We need to talk to the Project Editor |
| about how to do this. |
| ]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| The requirements specified in Stage 2 and reiterated in the rationale |
| of DR 221 (and echoed again in DR 303) specify that num_get<charT>:: |
| do_get() compares characters on the stream against the widened elements |
| of "012...abc...ABCX+-" |
| </p> |
| |
| <p> |
| An implementation is required to allow programs to instantiate the num_get |
| template on any charT that satisfies the requirements on a user-defined |
| character type. These requirements do not include the ability of the |
| character type to be equality comparable (the char_traits template must |
| be used to perform tests for equality). Hence, the num_get template cannot |
| be implemented to support any arbitrary character type. The num_get template |
| must either make the assumption that the character type is equality-comparable |
| (as some popular implementations do), or it may use char_traits<charT> to do |
| the comparisons (some other popular implementations do that). This diversity |
| of approaches makes it difficult to write portable programs that attempt to |
| instantiate the num_get template on user-defined types. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Kona: the heart of the problem is that we're theoretically |
| supposed to use traits classes for all fundamental character |
| operations like assignment and comparison, but facets don't have |
| traits parameters. This is a fundamental design flaw and it |
| appears all over the place, not just in this one place. It's not |
| clear what the correct solution is, but a thorough review of facets |
| and traits is in order. The LWG considered and rejected the |
| possibility of changing numeric facets to use narrowing instead of |
| widening. This may be a good idea for other reasons (see issue |
| <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 |
| issue. Whether we use widen or narrow the <tt>num_get</tt> facet |
| still has no idea which traits class the user wants to use for |
| the comparison, because only streams, not facets, are passed traits |
| classes. The standard does not require that two different |
| traits classes with the same <tt>char_type</tt> must necessarily |
| have the same behavior.]</i></p> |
| |
| <p>Informally, one possibility: require that some of the basic |
| character operations, such as <tt>eq</tt>, <tt>lt</tt>, |
| and <tt>assign</tt>, must behave the same way for all traits classes |
| with the same <tt>char_type</tt>. If we accept that limitation on |
| traits classes, then the facet could reasonably be required to |
| use <tt>char_traits<charT></tt></p>. |
| |
| <hr> |
| <a name="430"><h3>430. valarray subset operations</h3></a><p><b>Section:</b> 26.5.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> |
| <p> |
| The standard fails to specify the behavior of valarray::operator[](slice) |
| and other valarray subset operations when they are passed an "invalid" |
| slice object, i.e., either a slice that doesn't make sense at all (e.g., |
| slice (0, 1, 0) or one that doesn't specify a valid subset of the valarray |
| object (e.g., slice (2, 1, 1) for a valarray of size 1). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Kona: the LWG believes that invalid slices should invoke |
| undefined behavior. Valarrays are supposed to be designed for high |
| performance, so we don't want to require specific checking. We |
| need wording to express this decision.]</i></p> |
| <hr> |
| <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.default.con.req"> [lib.default.con.req]</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> |
| <p>Clause 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.default.con.req"> [lib.default.con.req]</a> paragraph 4 says that implementations |
| are permitted to supply containers that are unable to cope with |
| allocator instances and that container implementations may assume |
| that all instances of an allocator type compare equal. We gave |
| implementers this latitude as a temporary hack, and eventually we |
| want to get rid of it. What happens when we're dealing with |
| allocators that <i>don't</i> compare equal? |
| </p> |
| |
| <p>In particular: suppose that <tt>v1</tt> and <tt>v2</tt> are both |
| objects of type <tt>vector<int, my_alloc></tt> and that |
| <tt>v1.get_allocator() != v2.get_allocator()</tt>. What happens if |
| we write <tt>v1.swap(v2)</tt>? Informally, three possibilities:</p> |
| |
| <p>1. This operation is illegal. Perhaps we could say that an |
| implementation is required to check and to throw an exception, or |
| perhaps we could say it's undefined behavior.</p> |
| <p>2. The operation performs a slow swap (i.e. using three |
| invocations of <tt>operator=</tt>, leaving each allocator with its |
| original container. This would be an O(N) operation.</p> |
| <p>3. The operation swaps both the vectors' contents and their |
| allocators. This would be an O(1) operation. That is:</p> |
| <blockquote> |
| <pre> my_alloc a1(...); |
| my_alloc a2(...); |
| assert(a1 != a2); |
| |
| vector<int, my_alloc> v1(a1); |
| vector<int, my_alloc> v2(a2); |
| assert(a1 == v1.get_allocator()); |
| assert(a2 == v2.get_allocator()); |
| |
| v1.swap(v2); |
| assert(a1 == v2.get_allocator()); |
| assert(a2 == v1.get_allocator()); |
| </pre> |
| </blockquote> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Kona: This is part of a general problem. We need a paper |
| saying how to deal with unequal allocators in general.]</i></p> |
| |
| <p><i>[pre-Sydney: Howard argues for option 3 in n1599.]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| What requirements does the standard place on equality comparisons between |
| iterators that refer to elements of different containers. For example, if |
| v1 and v2 are empty vectors, is v1.end() == v2.end() allowed to yield true? |
| Is it allowed to throw an exception? |
| </p> |
| |
| <p> |
| The standard appears to be silent on both questions. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Sydney: The intention is that comparing two iterators from |
| different containers is undefined, but it's not clear if we say that, |
| or even whether it's something we should be saying in clause 23 or in |
| clause 24. Intuitively we might want to say that equality is defined |
| only if one iterator is reachable from another, but figuring out how |
| to say it in any sensible way is a bit tricky: reachability is defined |
| in terms of equality, so we can't also define equality in terms of |
| reachability. |
| ]</i></p> |
| |
| <hr> |
| <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> |
| <pre> basic_filebuf *basic_filebuf::open(const char *, ios_base::open_mode); |
| </pre> |
| |
| <p>should be supplemented with the overload:</p> |
| |
| <pre> basic_filebuf *basic_filebuf::open(const wchar_t *, ios_base::open_mode); |
| </pre> |
| |
| <p> |
| Depending on the operating system, one of these forms is fundamental and |
| the other requires an implementation-defined mapping to determine the |
| actual filename. |
| </p> |
| |
| <p><i>[Sydney: Yes, we want to allow wchar_t filenames. Bill will |
| provide wording.]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change from:</p> |
| <blockquote> |
| <pre>basic_filebuf<charT,traits>* open( |
| const char* s, |
| ios_base::openmode mode ); |
| </pre> |
| |
| <p> |
| Effects: If is_open() != false, returns a null pointer. |
| Otherwise, initializes the filebuf as required. It then |
| opens a file, if possible, whose name is the NTBS s ("as if" |
| by calling std::fopen(s,modstr)).</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <pre>basic_filebuf<charT,traits>* open( |
| const char* s, |
| ios_base::openmode mode ); |
| |
| basic_filebuf<charT,traits>* open( |
| const wchar_t* ws, |
| ios_base::openmode mode ); |
| </pre> |
| |
| <p> |
| Effects: If is_open() != false, returns a null pointer. |
| Otherwise, initializes the filebuf as required. It then |
| opens a file, if possible, whose name is the NTBS s ("as if" |
| by calling std::fopen(s,modstr)). |
| For the second signature, the NTBS s is determined from the |
| WCBS ws in an implementation-defined manner. |
| </p> |
| |
| <p> |
| (NOTE: For a system that "naturally" represents a filename |
| as a WCBS, the NTBS s in the first signature may instead |
| be mapped to a WCBS; if so, it follows the same mapping |
| rules as the first argument to open.) |
| </p> |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Slightly controversial, but by a 7-1 straw poll the LWG agreed to move |
| this to Ready. The controversy was because the mapping between wide |
| names and files in a filesystem is implementation defined. The |
| counterargument, which most but not all LWG members accepted, is that |
| the mapping between narrow files names and files is also |
| implemenation defined.</p> |
| |
| <p><i>[Lillehammer: Moved back to "open" status, at Beman's urging. |
| (1) Why just basic_filebuf, instead of also basic_fstream (and |
| possibly other things too). (2) Why not also constructors that take |
| std::basic_string? (3) We might want to wait until we see Beman's |
| filesystem library; we might decide that it obviates this.]</i></p> |
| |
| <hr> |
| <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> |
| |
| <p>The C++ Standard effectively requires that the traditional C headers |
| (of the form <xxx.h>) be defined in terms of the newer C++ |
| headers (of the form <cxxx>). Clauses 17.4.1.2/4 and D.5 combine |
| to require that:</p> |
| |
| <ul> |
| <li>Including the header <cxxx> declares a C name in namespace std.</li> |
| |
| <li> Including the header <xxx.h> declares a C name in namespace std |
| (effectively by including <cxxx>), then imports it into the global |
| namespace with an individual using declaration.</li> |
| </ul> |
| |
| <p> |
| The rules were left in this form despited repeated and heated objections |
| from several compiler vendors. The C headers are often beyond the direct |
| control of C++ implementors. In some organizations, it's all they can do |
| to get a few #ifdef __cplusplus tests added. Third-party library vendors |
| can perhaps wrap the C headers. But neither of these approaches supports |
| the drastic restructuring required by the C++ Standard. As a result, it is |
| still widespread practice to ignore this conformance requirement, nearly |
| seven years after the committee last debated this topic. Instead, what is |
| often implemented is: |
| </p> |
| |
| <ul> |
| <li> Including the header <xxx.h> declares a C name in the |
| global namespace.</li> |
| |
| <li> Including the header <cxxx> declares a C name in the |
| global namespace (effectively by including <xxx.h>), then |
| imports it into namespace std with an individual using declaration.</li> |
| </ul> |
| |
| <p> |
| The practical benefit for implementors with the second approach is that |
| they can use existing C library headers, as they are pretty much obliged |
| to do. The practical cost for programmers facing a mix of implementations |
| is that they have to assume weaker rules:</p> |
| |
| <ul> |
| <li> If you want to assuredly declare a C name in the global |
| namespace, include <xxx.h>. You may or may not also get the |
| declaration in namespace std.</li> |
| |
| <li> If you want to assuredly declare a C name in namespace std, |
| include <cxxx.h>. You may or may not also get the declaration in |
| the global namespace.</li> |
| </ul> |
| |
| <p> |
| There also exists the <i>possibility</i> of subtle differences due to |
| Koenig lookup, but there are so few non-builtin types defined in the C |
| headers that I've yet to see an example of any real problems in this |
| area. |
| </p> |
| |
| <p> |
| It is worth observing that the rate at which programmers fall afoul of |
| these differences has remained small, at least as measured by newsgroup |
| postings and our own bug reports. (By an overwhelming margin, the |
| commonest problem is still that programmers include <string> and can't |
| understand why the typename string isn't defined -- this a decade after |
| the committee invented namespace std, nominally for the benefit of all |
| programmers.) |
| </p> |
| |
| <p> |
| We should accept the fact that we made a serious mistake and rectify it, |
| however belatedly, by explicitly allowing either of the two schemes for |
| declaring C names in headers. |
| </p> |
| |
| <p><i>[Sydney: This issue has been debated many times, and will |
| certainly have to be discussed in full committee before any action |
| can be taken. However, the preliminary sentiment of the LWG was in |
| favor of the change. (6 yes, 0 no, 2 abstain) Robert Klarer |
| suggests that we might also want to undeprecate the |
| C-style <tt>.h</tt> headers.]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <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> |
| <p> |
| In 24.1.5 [lib.random.access.iterators], table 76 the operational |
| semantics for the expression "r -= n" are defined as "return r += -n". |
| This means, that the expression -n must be valid, which is not the case |
| for unsigned types. |
| </p> |
| |
| <p><i>[ |
| Sydney: Possibly not a real problem, since difference type is required |
| to be a signed integer type. However, the wording in the standard may |
| be less clear than we would like. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| To remove this limitation, I suggest to change the |
| operational semantics for this column to: |
| </p> |
| <code> |
| { Distance m = n; |
| if (m >= 0) |
| while (m--) --r; |
| else |
| while (m++) ++r; |
| return r; } |
| </code> |
| |
| <hr> |
| <a name="459"><h3>459. Requirement for widening in stage 2 is overspecification</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> 16 Mar 2004</p> |
| <p>When parsing strings of wide-character digits, the standard |
| requires the library to widen narrow-character "atoms" and compare |
| the widened atoms against the characters that are being parsed. |
| Simply narrowing the wide characters would be far simpler, and |
| probably more efficient. The two choices are equivalent except in |
| convoluted test cases, and many implementations already ignore the |
| standard and use narrow instead of widen.</p> |
| |
| <p> |
| First, I disagree that using narrow() instead of widen() would |
| necessarily have unfortunate performance implications. A possible |
| implementation of narrow() that allows num_get to be implemented |
| in a much simpler and arguably comparably efficient way as calling |
| widen() allows, i.e. without making a virtual call to do_narrow every |
| time, is as follows: |
| </p> |
| |
| <pre> inline char ctype<wchar_t>::narrow (wchar_t wc, char dflt) const |
| { |
| const unsigned wi = unsigned (wc); |
| |
| if (wi > UCHAR_MAX) |
| return typeid (*this) == typeid (ctype<wchar_t>) ? |
| dflt : do_narrow (wc, dflt); |
| |
| if (narrow_ [wi] < 0) { |
| const char nc = do_narrow (wc, dflt); |
| if (nc == dflt) |
| return dflt; |
| narrow_ [wi] = nc; |
| } |
| |
| return char (narrow_ [wi]); |
| } |
| </pre> |
| |
| <p> |
| Second, I don't think the change proposed in the issue (i.e., to use |
| narrow() instead of widen() during Stage 2) would be at all |
| drastic. Existing implementations with the exception of libstdc++ |
| currently already use narrow() so the impact of the change on programs |
| would presumably be isolated to just a single implementation. Further, |
| since narrow() is not required to translate alternate wide digit |
| 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 |
| their narrow equivalents (i.e., the portable source characters '0' |
| through '9'), the change does not necessarily imply that these |
| alternate digits would be treated as ordinary digits and accepted as |
| 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 |
| digit character, wc, to an ordinary digit in the basic source |
| character set unless the expression |
| (ctype<charT>::is(ctype_base::digit, wc) == true) holds. This in |
| turn is prohibited by the C standard (7.25.2.1.5, 7.25.2.1.5, and |
| 5.2.1, respectively) for charT of either char or wchar_t. |
| </p> |
| |
| <p><i>[Sydney: To a large extent this is a nonproblem. As long as |
| you're only trafficking in char and wchar_t we're only dealing with a |
| stable character set, so you don't really need either 'widen' or |
| 'narrow': can just use literals. Finally, it's not even clear whether |
| widen-vs-narrow is the right question; arguably we should be using |
| codecvt instead.]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change stage 2 so that implementations are permitted to use either |
| technique to perform the comparison:</p> |
| <ol> |
| <li> call widen on the atoms and compare (either by using |
| operator== or char_traits<charT>::eq) the input with |
| the widened atoms, or</li> |
| <li> call narrow on the input and compare the narrow input |
| with the atoms</li> |
| <li> do (1) or (2) only if charT is not char or wchar_t, |
| respectively; i.e., avoid calling widen or narrow |
| if it the source and destination types are the same</li> |
| </ol> |
| <hr> |
| <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.cstdint"> [lib.cstdint]</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> |
| <p> |
| 3.6.3 Termination spells out in detail the interleaving of static |
| destructor calls and calls to functions registered with atexit. To |
| match this behavior requires intimate cooperation between the code |
| that calls destructors and the exit/atexit machinery. The former |
| is tied tightly to the compiler; the latter is a primitive mechanism |
| inherited from C that traditionally has nothing to do with static |
| construction and destruction. The benefits of intermixing destructor |
| calls with atexit handler calls is questionable at best, and <i>very</i> |
| difficult to get right, particularly when mixing third-party C++ |
| libraries with different third-party C++ compilers and C libraries |
| supplied by still other parties. |
| </p> |
| |
| <p> |
| I believe the right thing to do is defer all static destruction |
| until after all atexit handlers are called. This is a change in |
| behavior, but one that is likely visible only to perverse test |
| suites. At the very least, we should <i>permit</i> deferred destruction |
| even if we don't require it. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[If this is to be changed, it should probably be changed by CWG. |
| At this point, however, the LWG is leaning toward NAD. Implementing |
| what the standard says is hard work, but it's not impossible and |
| most vendors went through that pain years ago. Changing this |
| behavior would be a user-visible change, and would break at least |
| one real application.]</i></p> |
| |
| <p> |
| </p> |
| <hr> |
| <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.meta.unary"> [lib.meta.unary]</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> |
| |
| <p> |
| TC1 CWG DR #84 effectively made the template<class Y> operator auto_ptr<Y>() |
| member of auto_ptr (20.4.5.3/4) obsolete. |
| </p> |
| |
| <p> |
| The sole purpose of this obsolete conversion member is to enable copy |
| initialization base from r-value derived (or any convertible types like |
| cv-types) case: |
| </p> |
| <pre>#include <memory> |
| using std::auto_ptr; |
| |
| struct B {}; |
| struct D : B {}; |
| |
| auto_ptr<D> source(); |
| int sink(auto_ptr<B>); |
| int x1 = sink( source() ); // #1 EDG - no suitable copy constructor |
| </pre> |
| |
| <p> |
| The excellent analysis of conversion operations that was given in the final |
| auto_ptr proposal |
| (http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/1997/N1128.pdf) |
| explicitly specifies this case analysis (case 4). DR #84 makes the analysis |
| wrong and actually comes to forbid the loophole that was exploited by the |
| auto_ptr designers. |
| </p> |
| |
| <p> |
| I didn't encounter any compliant compiler (e.g. EDG, GCC, BCC and VC) that |
| ever allowed this case. This is probably because it requires 3 user defined |
| conversions and in fact current compilers conform to DR #84. |
| </p> |
| |
| <p> |
| I was surprised to discover that the obsolete conversion member actually has |
| negative impact of the copy initialization base from l-value derived |
| case:</p> |
| <pre>auto_ptr<D> dp; |
| int x2 = sink(dp); // #2 EDG - more than one user-defined conversion applies |
| </pre> |
| |
| <p> |
| I'm sure that the original intention was allowing this initialization using |
| the template<class Y> auto_ptr(auto_ptr<Y>& a) constructor (20.4.5.1/4) but |
| since in this copy initialization it's merely user defined conversion (UDC) |
| and the obsolete conversion member is UDC with the same rank (for the early |
| overloading stage) there is an ambiguity between them. |
| </p> |
| |
| <p> |
| Removing the obsolete member will have impact on code that explicitly |
| invokes it: |
| </p> |
| <pre>int y = sink(source().operator auto_ptr<B>()); |
| </pre> |
| |
| <p> |
| IMHO no one ever wrote such awkward code and the reasonable workaround for |
| #1 is: |
| </p> |
| <pre>int y = sink( auto_ptr<B>(source()) ); |
| </pre> |
| |
| <p> |
| I was even more surprised to find out that after removing the obsolete |
| conversion member the initialization was still ill-formed: |
| int x3 = sink(dp); // #3 EDG - no suitable copy constructor |
| </p> |
| |
| <p> |
| This copy initialization semantically requires copy constructor which means |
| that both template conversion constructor and the auto_ptr_ref conversion |
| member (20.4.5.3/3) are required which is what was explicitly forbidden in |
| DR #84. This is a bit amusing case in which removing ambiguity results with |
| no candidates. |
| </p> |
| |
| <p> |
| I also found exception safety issue with auto_ptr related to auto_ptr_ref: |
| </p> |
| <pre>int f(auto_ptr<B>, std::string); |
| auto_ptr<B> source2(); |
| |
| // string constructor throws while auto_ptr_ref |
| // "holds" the pointer |
| int x4 = f(source2(), "xyz"); // #4 |
| </pre> |
| |
| <p> |
| The theoretic execution sequence that will cause a leak: |
| </p> |
| <ol> |
| <li>call auto_ptr<B>::operator auto_ptr_ref<B>()</li> |
| <li>call string::string(char const*) and throw</li> |
| </ol> |
| |
| <p> |
| According to 20.4.5.3/3 and 20.4.5/2 the auto_ptr_ref conversion member |
| returns auto_ptr_ref<Y> that holds *this and this is another defect since |
| the type of *this is auto_ptr<X> where X might be different from Y. Several |
| library vendors (e.g. SGI) implement auto_ptr_ref<Y> with Y* as member which |
| is much more reasonable. Other vendor implemented auto_ptr_ref as |
| defectively required and it results with awkward and catastrophic code: |
| int oops = sink(auto_ptr<B>(source())); // warning recursive on all control |
| paths |
| </p> |
| |
| <p> |
| Dave Abrahams noticed that there is no specification saying that |
| auto_ptr_ref copy constructor can't throw. |
| </p> |
| |
| <p> |
| My proposal comes to solve all the above issues and significantly simplify |
| auto_ptr implementation. One of the fundamental requirements from auto_ptr |
| is that it can be constructed in an intuitive manner (i.e. like ordinary |
| pointers) but with strict ownership semantics which yield that source |
| auto_ptr in initialization must be non-const. My idea is to add additional |
| constructor template with sole propose to generate ill-formed, diagnostic |
| required, instance for const auto_ptr arguments during instantiation of |
| declaration. This special constructor will not be instantiated for other |
| types which is achievable using 14.8.2/2 (SFINAE). Having this constructor |
| in hand makes the constructor template<class Y> auto_ptr(auto_ptr<Y> const&) |
| legitimate since the actual argument can't be const yet non const r-value |
| are acceptable. |
| </p> |
| |
| <p> |
| This implementation technique makes the "private auxiliary class" |
| auto_ptr_ref obsolete and I found out that modern C++ compilers (e.g. EDG, |
| GCC and VC) consume the new implementation as expected and allow all |
| intuitive initialization and assignment cases while rejecting illegal cases |
| that involve const auto_ptr arguments. |
| </p> |
| |
| <p>The proposed auto_ptr interface:</p> |
| |
| <pre>namespace std { |
| template<class X> class auto_ptr { |
| public: |
| typedef X element_type; |
| |
| // 20.4.5.1 construct/copy/destroy: |
| explicit auto_ptr(X* p=0) throw(); |
| auto_ptr(auto_ptr&) throw(); |
| template<class Y> auto_ptr(auto_ptr<Y> const&) throw(); |
| auto_ptr& operator=(auto_ptr&) throw(); |
| template<class Y> auto_ptr& operator=(auto_ptr<Y>) throw(); |
| ~auto_ptr() throw(); |
| |
| // 20.4.5.2 members: |
| X& operator*() const throw(); |
| X* operator->() const throw(); |
| X* get() const throw(); |
| X* release() throw(); |
| void reset(X* p=0) throw(); |
| |
| private: |
| template<class U> |
| auto_ptr(U& rhs, typename |
| unspecified_error_on_const_auto_ptr<U>::type = 0); |
| }; |
| } |
| </pre> |
| |
| <p> |
| One compliant technique to implement the unspecified_error_on_const_auto_ptr |
| helper class is using additional private auto_ptr member class template like |
| the following: |
| </p> |
| <pre>template<typename T> struct unspecified_error_on_const_auto_ptr; |
| |
| template<typename T> |
| struct unspecified_error_on_const_auto_ptr<auto_ptr<T> const> |
| { typedef typename auto_ptr<T>::const_auto_ptr_is_not_allowed type; }; |
| </pre> |
| |
| <p> |
| There are other techniques to implement this helper class that might work |
| better for different compliers (i.e. better diagnostics) and therefore I |
| suggest defining its semantic behavior without mandating any specific |
| implementation. IMO, and I didn't found any compiler that thinks otherwise, |
| 14.7.1/5 doesn't theoretically defeat the suggested technique but I suggest |
| verifying this with core language experts. |
| </p> |
| |
| <p><b>Further changes in standard text:</b></p> |
| <p>Remove section 20.4.5.3</p> |
| |
| <p>Change 20.4.5/2 to read something like: |
| Initializing auto_ptr<X> from const auto_ptr<Y> will result with unspecified |
| ill-formed declaration that will require unspecified diagnostic.</p> |
| |
| <p>Change 20.4.5.1/4,5,6 to read:</p> |
| |
| <pre>template<class Y> auto_ptr(auto_ptr<Y> const& a) throw();</pre> |
| <p> 4 Requires: Y* can be implicitly converted to X*.</p> |
| <p> 5 Effects: Calls const_cast<auto_ptr<Y>&>(a).release().</p> |
| <p> 6 Postconditions: *this holds the pointer returned from a.release().</p> |
| |
| <p>Change 20.4.5.1/10</p> |
| <pre>template<class Y> auto_ptr& operator=(auto_ptr<Y> a) throw(); |
| </pre> |
| <p> |
| 10 Requires: Y* can be implicitly converted to X*. The expression delete |
| get() is well formed. |
| </p> |
| |
| <p>LWG TC DR #127 is obsolete.</p> |
| |
| <p> |
| Notice that the copy constructor and copy assignment operator should remain |
| as before and accept non-const auto_ptr& since they have effect on the form |
| of the implicitly declared copy constructor and copy assignment operator of |
| class that contains auto_ptr as member per 12.8/5,10: |
| </p> |
| <pre>struct X { |
| // implicit X(X&) |
| // implicit X& operator=(X&) |
| auto_ptr<D> aptr_; |
| }; |
| </pre> |
| |
| <p> |
| In most cases this indicates about sloppy programming but preserves the |
| current auto_ptr behavior. |
| </p> |
| |
| <p> |
| Dave Abrahams encouraged me to suggest fallback implementation in case that |
| my suggestion that involves removing of auto_ptr_ref will not be accepted. |
| In this case removing the obsolete conversion member to auto_ptr<Y> and |
| 20.4.5.3/4,5 is still required in order to eliminate ambiguity in legal |
| cases. The two constructors that I suggested will co exist with the current |
| members but will make auto_ptr_ref obsolete in initialization contexts. |
| auto_ptr_ref will be effective in assignment contexts as suggested in DR |
| #127 and I can't see any serious exception safety issues in those cases |
| (although it's possible to synthesize such). auto_ptr_ref<X> semantics will |
| have to be revised to say that it strictly holds pointer of type X and not |
| reference to an auto_ptr for the favor of cases in which auto_ptr_ref<Y> is |
| constructed from auto_ptr<X> in which X is different from Y (i.e. assignment |
| from r-value derived to base). |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Redmond: punt for the moment. We haven't decided yet whether we |
| want to fix auto_ptr for C++-0x, or remove it and replace it with |
| move_ptr and unique_ptr.]</i></p> |
| <hr> |
| <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> |
| <p> |
| Today, my colleagues and me wasted a lot of time. After some time, I |
| found the problem. It could be reduced to the following short example: |
| </p> |
| |
| <pre> #include <string> |
| int main() { std::string( 0 ); } |
| </pre> |
| |
| <p>The problem is that the tested compilers (GCC 2.95.2, GCC 3.3.1 and |
| Comeau online) compile the above without errors or warnings! The |
| programs (at least for the GCC) resulted in a SEGV.</p> |
| |
| <p>I know that the standard explicitly states that the ctor of string |
| requires a char* which is not zero. STLs could easily detect the above |
| case with a private ctor for basic_string which takes a single 'int' |
| argument. This would catch the above code at compile time and would not |
| ambiguate any other legal ctors.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Redmond: No great enthusiasm for doing this. If we do, |
| however, we want to do it for all places that take <tt>charT*</tt> |
| pointers, not just the single-argument constructor. The other |
| question is whether we want to catch this at compile time (in which |
| case we catch the error of a literal 0, but not an expression whose |
| value is a null pointer), at run time, or both.]</i></p> |
| |
| <hr> |
| <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> |
| |
| <p> |
| The standard doesn't prohibit the destructors (or any other special |
| functions) of containers' elements invoked from a member function |
| of the container from "recursively" calling the same (or any other) |
| member function on the same container object, potentially while the |
| container is in an intermediate state, or even changing the state |
| of the container object while it is being modified. This may result |
| in some surprising (i.e., undefined) behavior. |
| </p> |
| |
| <p>Read email thread starting with c++std-lib-13637 for more.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add to Container Requirements the following new paragraph:</p> |
| |
| <pre> Unless otherwise specified, the behavior of a program that |
| invokes a container member function f from a member function |
| g of the container's value_type on a container object c that |
| called g from its mutating member function h, is undefined. |
| I.e., if v is an element of c, directly or indirectly calling |
| c.h() from v.g() called from c.f(), is undefined. |
| </pre> |
| |
| <p><i>[Redmond: This is a real issue, but it's probably a clause 17 |
| issue, not clause 23. We get the same issue, for example, if we |
| try to destroy a stream from one of the stream's callback functions.]</i></p> |
| |
| |
| <hr> |
| <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.type.info"> [lib.type.info]</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> |
| |
| <p>[lib.exception] specifies the following:</p> |
| <pre> exception (const exception&) throw(); |
| exception& operator= (const exception&) throw(); |
| |
| -4- Effects: Copies an exception object. |
| -5- Notes: The effects of calling what() after assignment |
| are implementation-defined. |
| </pre> |
| |
| <p> |
| First, does the Note only apply to the assignment operator? If so, |
| what are the effects of calling what() on a copy of an object? Is |
| the returned pointer supposed to point to an identical copy of |
| the NTBS returned by what() called on the original object or not? |
| </p> |
| |
| <p> |
| Second, is this Note intended to extend to all the derived classes |
| in section 19? I.e., does the standard provide any guarantee for |
| the effects of what() called on a copy of any of the derived class |
| described in section 19? |
| </p> |
| |
| <p> |
| Finally, if the answer to the first question is no, I believe it |
| constitutes a defect since throwing an exception object typically |
| implies invoking the copy ctor on the object. If the answer is yes, |
| then I believe the standard ought to be clarified to spell out |
| exactly what the effects are on the copy (i.e., after the copy |
| ctor was called). |
| </p> |
| |
| <p><i>[Redmond: Yes, this is fuzzy. The issue of derived classes is |
| fuzzy too.]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <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> |
| <p> |
| Most ctype member functions come in two forms: one that operates |
| on a single character at a time and another form that operates |
| on a range of characters. Both forms are typically described by |
| a single Effects and/or Returns clause. |
| </p> |
| <p> |
| The Returns clause of each of the single-character non-virtual forms |
| suggests that the function calls the corresponding single character |
| virtual function, and that the array form calls the corresponding |
| virtual array form. Neither of the two forms of each virtual member |
| function is required to be implemented in terms of the other. |
| </p> |
| <p> |
| There are three problems: |
| </p> |
| <p> |
| 1. One is that while the standard does suggest that each non-virtual |
| member function calls the corresponding form of the virtual function, |
| it doesn't actually explicitly require it. |
| </p> |
| <p> |
| Implementations that cache results from some of the virtual member |
| functions for some or all values of their arguments might want to |
| call the array form from the non-array form the first time to fill |
| the cache and avoid any or most subsequent virtual calls. Programs |
| that rely on each form of the virtual function being called from |
| the corresponding non-virtual function will see unexpected behavior |
| when using such implementations. |
| </p> |
| <p> |
| 2. The second problem is that either form of each of the virtual |
| functions can be overridden by a user-defined function in a derived |
| class to return a value that is different from the one produced by |
| the virtual function of the alternate form that has not been |
| overriden. |
| </p> |
| <p> |
| Thus, it might be possible for, say, ctype::widen(c) to return one |
| value, while for ctype::widen(&c, &c + 1, &wc) to set |
| wc to another value. This is almost certainly not intended. Both |
| forms of every function should be required to return the same result |
| for the same character, otherwise the same program using an |
| implementation that calls one form of the functions will behave |
| differently than when using another implementation that calls the |
| other form of the function "under the hood." |
| </p> |
| <p> |
| 3. The last problem is that the standard text fails to specify whether |
| one form of any of the virtual functions is permitted to be implemented |
| in terms of the other form or not, and if so, whether it is required |
| or permitted to call the overridden virtual function or not. |
| </p> |
| <p> |
| Thus, a program that overrides one of the virtual functions so that |
| it calls the other form which then calls the base member might end |
| up in an infinite loop if the called form of the base implementation |
| of the function in turn calls the other form. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Lillehammer: Part of this isn't a real problem. We already talk about |
| caching. 22.1.1/6 But part is a real problem. ctype virtuals may call |
| each other, so users don't know which ones to override to avoid avoid |
| infinite loops.</p> |
| |
| <p>This is a problem for all facet virtuals, not just ctype virtuals, |
| so we probably want a blanket statement in clause 22 for all |
| facets. The LWG is leaning toward a blanket prohibition, that a |
| facet's virtuals may never call each other. We might want to do that |
| in clause 27 too, for that matter. A review is necessary. Bill will |
| provide wording.</p> |
| <hr> |
| <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> |
| <p>Nothing in the standard appears to make this program ill-formed:</p> |
| |
| <pre> struct C { |
| void* operator new( size_t s ) { return ::operator new( s ); } |
| // NOTE: this hides in-place and nothrow new |
| }; |
| |
| int main() { |
| vector<C> v; |
| v.push_back( C() ); |
| } |
| </pre> |
| |
| <p>Is that intentional? We should clarify whether or not we intended |
| to require containers to support types that define their own special |
| versions of <tt>operator new</tt>.</p> |
| |
| <p><i>[ |
| Lillehammer: A container will definitely never use this overridden |
| operator new, but whether it will fail to compile is unclear from the |
| standard. Are containers supposed to use qualified or unqualified |
| placement new? 20.4.1.1 is somewhat relevant, but the standard |
| doesn't make it completely clear whether containers have to use |
| Allocator::construct(). If containers don't use it, the details of how |
| containers use placement new are unspecified. That is the real bug, |
| but it needs to be fixed as part of the allocator overhaul. Weak |
| support that the eventual solution should make this code well formed. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <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> |
| <p>(Based on recent comp.std.c++ discussion)</p> |
| |
| <p>Pair (and tuple) should specialize std::swap to work in terms of |
| std::swap on their components. For example, there's no obvious reason |
| why swapping two objects of type pair<vector<int>, |
| list<double> > should not take O(1).</p> |
| <p><b>Proposed resolution:</b></p> |
| |
| |
| <p><i>[Lillehammer: We agree it should be swappable. Howard will |
| provide wording.]</i></p> |
| |
| <hr> |
| <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 Jefferson <b>Date:</b> 16 Sep 2004</p> |
| <p>From comp.std.c++:</p> |
| |
| <p> |
| I note that given an input iterator a for type T, |
| then *a only has to be "convertable to T", not actually of type T. |
| </p> |
| |
| <p>Firstly, I can't seem to find an exact definition of "convertable to T". |
| While I assume it is the obvious definition (an implicit conversion), I |
| can't find an exact definition. Is there one?</p> |
| |
| <p>Slightly more worryingly, there doesn't seem to be any restriction on |
| the this type, other than it is "convertable to T". Consider two input |
| iterators a and b. I would personally assume that most people would |
| expect *a==*b would perform T(*a)==T(*b), however it doesn't seem that |
| the standard requires that, and that whatever type *a is (call it U) |
| could have == defined on it with totally different symantics and still |
| be a valid inputer iterator.</p> |
| |
| <p>Is this a correct reading? When using input iterators should I write |
| T(*a) all over the place to be sure that the object i'm using is the |
| class I expect?</p> |
| |
| <p>This is especially a nuisance for operations that are defined to be |
| "convertible to bool". (This is probably allowed so that |
| implementations could return say an int and avoid an unnessary |
| conversion. However all implementations I have seen simply return a |
| bool anyway. Typical implemtations of STL algorithms just write |
| things like <tt>while(a!=b && *a!=0)</tt>. But strictly |
| speaking, there are lots of types that are convertible to T but |
| that also overload the appropriate operators so this doesn't behave |
| as expected.</p> |
| |
| <p>If we want to make code like this legal (which most people seem to |
| expect), then we'll need to tighten up what we mean by "convertible |
| to T".</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Lillehammer: The first part is NAD, since "convertible" is |
| well-defined in core. The second part is basically about pathological |
| overloads. It's a minor problem but a real one. So leave open for |
| now, hope we solve it as part of iterator redesign.]</i></p> |
| <hr> |
| <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 Jefferson <b>Date:</b> 13 Oct 2004</p> |
| <p> |
| The note on 24.1.2 Output iterators insufficently limits what can be |
| performed on output iterators. While it requires that each iterator is |
| progressed through only once and that each iterator is written to only |
| once, it does not require the following things:</p> |
| |
| <p>Note: Here it is assumed that x is an output iterator of type X which |
| has not yet been assigned to.</p> |
| |
| <p>a) That each value of the output iterator is written to: |
| The standard allows: |
| ++x; ++x; ++x; |
| </p> |
| |
| <p> |
| b) That assignments to the output iterator are made in order |
| X a(x); ++a; *a=1; *x=2; is allowed |
| </p> |
| |
| <p> |
| c) Chains of output iterators cannot be constructed: |
| X a(x); ++a; X b(a); ++b; X c(b); ++c; is allowed, and under the current |
| wording (I believe) x,a,b,c could be written to in any order. |
| </p> |
| |
| <p>I do not believe this was the intension of the standard?</p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[Lillehammer: Real issue. There are lots of constraints we |
| intended but didn't specify. Should be solved as part of iterator |
| redesign.]</i></p> |
| <hr> |
| <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> |
| <p> |
| rotate takes 3 iterators: first, middle and last which point into a |
| sequence, and rearranges the sequence such that the subrange [middle, |
| last) is now at the beginning of the sequence and the subrange [first, |
| middle) follows. The return type is void. |
| </p> |
| |
| <p> |
| In many use cases of rotate, the client needs to know where the |
| subrange [first, middle) starts after the rotate is performed. This |
| might look like: |
| </p> |
| <pre> rotate(first, middle, last); |
| Iterator i = advance(first, distance(middle, last)); |
| </pre> |
| |
| <p> |
| Unless the iterators are random access, the computation to find the |
| start of the subrange [first, middle) has linear complexity. However, |
| it is not difficult for rotate to return this information with |
| negligible additional computation expense. So the client could code: |
| </p> |
| <pre> Iterator i = rotate(first, middle, last); |
| </pre> |
| |
| <p> |
| and the resulting program becomes significantly more efficient. |
| </p> |
| |
| <p> |
| While the backwards compatibility hit with this change is not zero, it |
| 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 |
| a significant benefit to the change. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25p2, change:</p> |
| <pre> template<class ForwardIterator> |
| void rotate(ForwardIterator first, ForwardIterator middle, |
| ForwardIterator last); |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> template<class ForwardIterator> |
| ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, |
| ForwardIterator last); |
| </pre> |
| |
| <p>In 25.2.10, change:</p> |
| |
| <pre> template<class ForwardIterator> |
| void rotate(ForwardIterator first, ForwardIterator middle, |
| ForwardIterator last); |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> template<class ForwardIterator> |
| ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, |
| ForwardIterator last); |
| </pre> |
| |
| <p>In 25.2.10 insert a new paragraph after p1:</p> |
| |
| <blockquote> |
| <p><b>Returns</b>: <tt>first + (last - middle)</tt>.</p> |
| </blockquote> |
| |
| <p><i>[ |
| The LWG agrees with this idea, but has one quibble: we want to make |
| sure not to give the impression that the function "advance" is |
| actually called, just that the nth iterator is returned. (Calling |
| advance is observable behavior, since users can specialize it for |
| their own iterators.) Howard will provide wording. |
| ]</i></p> |
| |
| <p><i>[Howard provided wording for mid-meeting-mailing Jun. 2005.]</i></p> |
| |
| <hr> |
| <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> |
| <p>Various clauses other than clause 25 make use of iterator arithmetic not |
| supported by the iterator category in question. |
| Algorithms in clause 25 are exceptional because of 25 [lib.algorithms], |
| paragraph 9, but this paragraph does not provide semantics to the |
| expression "iterator - n", where n denotes a value of a distance type |
| between iterators.</p> |
| |
| <p>1) Examples of current wording:</p> |
| |
| <p>Current wording outside clause 25:</p> |
| |
| <p> |
| 23.2.2.4 [lib.list.ops], paragraphs 19-21: "first + 1", "(i - 1)", |
| "(last - first)" |
| 23.3.1.1 [lib.map.cons], paragraph 4: "last - first" |
| 23.3.2.1 [lib.multimap.cons], paragraph 4: "last - first" |
| 23.3.3.1 [lib.set.cons], paragraph 4: "last - first" |
| 23.3.4.1 [lib.multiset.cons], paragraph 4: "last - first" |
| 24.4.1 [lib.reverse.iterators], paragraph 1: "(i - 1)" |
| </p> |
| |
| <p> |
| [Important note: The list is not complete, just an illustration. The |
| same issue might well apply to other paragraphs not listed here.]</p> |
| |
| <p>None of these expressions is valid for the corresponding iterator |
| category.</p> |
| |
| <p>Current wording in clause 25:</p> |
| |
| <p> |
| 25.1.1 [lib.alg.foreach], paragraph 1: "last - 1" |
| 25.1.3 [lib.alg.find.end], paragraph 2: "[first1, last1 - |
| (last2-first2))" |
| 25.2.8 [lib.alg.unique], paragraph 1: "(i - 1)" |
| 25.2.8 [lib.alg.unique], paragraph 5: "(i - 1)" |
| </p> |
| |
| <p> |
| However, current wording of 25 [lib.algorithms], paragraph 9 covers |
| neither of these four cases:</p> |
| |
| <p>Current wording of 25 [lib.algorithms], paragraph 9:</p> |
| |
| <p> |
| "In the description of the algorithms operator + and - are used for some |
| of the iterator categories for which they do not have to be defined. In |
| these cases the semantics of a+n is the same as that of</p> |
| <pre>{X tmp = a; |
| advance(tmp, n); |
| return tmp; |
| } |
| </pre> |
| <p>and that of b-a is the same as of return distance(a, b)"</p> |
| |
| <p> |
| This paragrpah does not take the expression "iterator - n" into account, |
| where n denotes a value of a distance type between two iterators [Note: |
| According to current wording, the expression "iterator - n" would be |
| resolved as equivalent to "return distance(n, iterator)"]. Even if the |
| expression "iterator - n" were to be reinterpreted as equivalent to |
| "iterator + -n" [Note: This would imply that "a" and "b" were |
| interpreted implicitly as values of iterator types, and "n" as value of |
| a distance type], then 24.3.4/2 interfers because it says: "Requires: n |
| may be negative only for random access and bidirectional iterators.", |
| and none of the paragraphs quoted above requires the iterators on which |
| the algorithms operate to be of random access or bidirectional category. |
| </p> |
| |
| <p>2) Description of intended behavior:</p> |
| |
| <p> |
| For the rest of this Defect Report, it is assumed that the expression |
| "iterator1 + n" and "iterator1 - iterator2" has the semantics as |
| described in current 25 [lib.algorithms], paragraph 9, but applying to |
| all clauses. The expression "iterator1 - n" is equivalent to an |
| result-iterator for which the expression "result-iterator + n" yields an |
| iterator denoting the same position as iterator1 does. The terms |
| "iterator1", "iterator2" and "result-iterator" shall denote the value of |
| an iterator type, and the term "n" shall denote a value of a distance |
| type between two iterators.</p> |
| |
| <p> |
| All implementations known to the author of this Defect Report comply |
| with these assumptions. |
| No impact on current code is expected.</p> |
| |
| <p>3) Proposed fixes:</p> |
| |
| |
| <p>Change 25 [lib.algorithms], paragraph 9 to:</p> |
| |
| <p> |
| "In the description of the algorithms operator + and - are used for some |
| of the iterator categories for which they do not have to be defined. In |
| this paragraph, a and b denote values of an iterator type, and n denotes |
| a value of a distance type between two iterators. In these cases the |
| semantics of a+n is the same as that of</p> |
| <pre>{X tmp = a; |
| advance(tmp, n); |
| return tmp; |
| } |
| </pre> |
| <p>,the semantics of a-n denotes the value of an iterator i for which the |
| following condition holds: |
| advance(i, n) == a, |
| and that of b-a is the same as of |
| return distance(a, b)". |
| </p> |
| |
| <p>Comments to the new wording:</p> |
| |
| <p> |
| a) The wording " In this paragraph, a and b denote values of an iterator |
| type, and n denotes a value of a distance type between two iterators." |
| was added so the expressions "b-a" and "a-n" are distinguished regarding |
| the types of the values on which they operate. |
| b) The wording ",the semantics of a-n denotes the value of an iterator i |
| for which the following condition holds: advance(i, n) == a" was added |
| to cover the expression 'iterator - n'. The wording "advance(i, n) == a" |
| was used to avoid a dependency on the semantics of a+n, as the wording |
| "i + n == a" would have implied. However, such a dependency might well |
| be deserved. |
| c) DR 225 is not considered in the new wording. |
| </p> |
| |
| <p> |
| Proposed fixes regarding invalid iterator arithmetic expressions outside |
| clause 25:</p> |
| |
| <p> |
| Either |
| a) Move modified 25 [lib.algorithms], paragraph 9 (as proposed above) |
| before any current invalid iterator arithmetic expression. In that case, |
| the first sentence of 25 [lib.algorithms], paragraph 9, need also to be |
| modified and could read: "For the rest of this International Standard, |
| ...." / "In the description of the following clauses including this |
| ...." / "In the description of the text below ..." etc. - anyways |
| substituting the wording "algorithms", which is a straight reference to |
| clause 25. |
| In that case, 25 [lib.algorithms] paragraph 9 will certainly become |
| obsolete. |
| Alternatively, |
| b) Add an appropiate paragraph similar to resolved 25 [lib.algorithms], |
| paragraph 9, to the beginning of each clause containing invalid iterator |
| arithmetic expressions. |
| Alternatively, |
| c) Fix each paragraph (both current wording and possible resolutions of |
| DRs) containing invalid iterator arithmetic expressions separately. |
| </p> |
| |
| <p>5) References to other DRs:</p> |
| |
| <p> |
| See DR 225. |
| See DR 237. The resolution could then also read "Linear in last - |
| first". |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Lillehammer: Minor issue, but real. We have a blanket statement |
| about this in 25/11. But (a) it should be in 17, not 25; and (b) it's |
| not quite broad enough, because there are some arithmetic expressions |
| it doesn't cover. Bill will provide wording.]</i></p> |
| |
| <hr> |
| <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> |
| <p> |
| Problem: |
| The iterator requirements for partition() and stable_partition() [25.2.12] |
| are listed as BidirectionalIterator, however, there are efficient algorithms |
| for these functions that only require ForwardIterator that have been known |
| since before the standard existed. The SGI implementation includes these (see |
| <a href="http://www.sgi.com/tech/stl/partition.html">http://www.sgi.com/tech/stl/partition.html</a> |
| and |
| <a href="http://www.sgi.com/tech/stl/stable_partition.html">http://www.sgi.com/tech/stl/stable_partition.html</a>). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 25.2.12 from </p> |
| <blockquote><pre>template<class BidirectionalIterator, class Predicate> |
| BidirectionalIterator partition(BidirectionalIterato r first, |
| BidirectionalIterator last, |
| Predicate pred); |
| </pre></blockquote> |
| <p>to </p> |
| <blockquote><pre>template<class ForwardIterator, class Predicate> |
| ForwardIterator partition(ForwardIterator first, |
| ForwardIterator last, |
| Predicate pred); |
| </pre></blockquote> |
| <p>Change the complexity from </p> |
| |
| <blockquote><p> |
| At most (last - first)/2 swaps are done. Exactly (last - first) |
| applications of the predicate are done. |
| </p></blockquote> |
| |
| <p>to </p> |
| |
| <blockquote><p> |
| If ForwardIterator is a bidirectional_iterator, at most (last - first)/2 |
| swaps are done; otherwise at most (last - first) swaps are done. Exactly |
| (last - first) applications of the predicate are done. |
| </p></blockquote> |
| |
| <p><b>Rationale:</b></p> |
| Partition is a "foundation" algorithm useful in many contexts (like sorting |
| as just one example) - my motivation for extending it to include forward |
| iterators is slist - without this extension you can't partition an slist |
| (without writing your own partition). Holes like this in the standard |
| library weaken the argument for generic programming (ideally I'd be able |
| to provide a library that would refine std::partition() to other concepts |
| without fear of conflicting with other libraries doing the same - but |
| that is a digression). I consider the fact that partition isn't defined |
| to work for ForwardIterator a minor embarrassment. |
| |
| <p><i>[Mont Tremblant: Moved to Open, request motivation and use cases |
| by next meeting. Sean provided further rationale by post-meeting |
| mailing.]</i></p> |
| |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Christopher Conrade Zseleghovski <b>Date:</b> 7 Jun 2005</p> |
| <p> |
| Motivation: |
| </p> |
| |
| <p> |
| This requirement seems obvious to me, it is the essence of code modularity. |
| I have complained to Mr. Plauger that the Dinkumware library does not |
| observe this principle but he objected that this behaviour is not covered in |
| the standard. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Append the following point to 22.1.1.1.1: |
| </p> |
| |
| <p> |
| 6. The implementation of a facet of Table 52 parametrized with an |
| InputIterator/OutputIterator should use that iterator only as character |
| source/sink respectively. |
| For a *_get facet, it means that the value received depends only on the |
| sequence of input characters and not on how they are accessed. |
| For a *_put facet, it means that the sequence of characters output depends |
| only on the value to be formatted and not of how the characters are stored. |
| </p> |
| |
| <p><i>[ |
| Berlin: Moved to Open, Need to clean up this area to make it clear |
| locales don't have to contain open ended sets of facets. Jack, Howard, |
| Bill. |
| ]</i></p> |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> P.J. Plauger <b>Date:</b> 20 Jun 2005</p> |
| <p> |
| a) In 22.2.1.1 para. 2 we refer to "the instantiations required in Table |
| 51" to refer to the facet *objects* associated with a locale. And we |
| almost certainly mean just those associated with the default or "C" |
| locale. Otherwise, you can't switch to a locale that enforces a different |
| mapping between narrow and wide characters, or that defines additional |
| uppercase characters. |
| </p> |
| |
| <p> |
| b) 22.2.1.5 para. 3 (codecvt) has the same issues. |
| </p> |
| |
| <p> |
| c) 22.2.1.5.2 (do_unshift) is even worse. It *forbids* the generation of |
| a homing sequence for the basic character set, which might very well need |
| one. |
| </p> |
| |
| <p> |
| d) 22.2.1.5.2 (do_length) likewise dictates that the default mapping |
| between wide and narrow characters be taken as one-for-one. |
| </p> |
| |
| <p> |
| e) 22.2.2 para. 2 (num_get/put) is both muddled and vacuous, as far as |
| I can tell. The muddle is, as before, calling Table 51 a list of |
| instantiations. But the constraint it applies seems to me to cover |
| *all* defined uses of num_get/put, so why bother to say so? |
| </p> |
| |
| <p> |
| f) 22.2.3.1.2 para. 1(do_decimal_point) says "The required instantiations |
| return '.' or L'.'.) Presumably this means "as appropriate for the |
| character type. But given the vague definition of "required" earlier, |
| this overrules *any* change of decimal point for non "C" locales. |
| Surely we don't want to do that. |
| </p> |
| |
| <p> |
| g) 22.2.3.1.2 para. 2 (do_thousands_sep) says "The required instantiations |
| return ',' or L','.) As above, this probably means "as appropriate for the |
| character type. But this overrules the "C" locale, which requires *no* |
| character ('\0') for the thousands separator. Even if we agree that we |
| don't mean to block changes in decimal point or thousands separator, |
| we should also eliminate this clear incompatibility with C. |
| </p> |
| |
| <p> |
| h) 22.2.3.1.2 para. 2 (do_grouping) says "The required instantiations |
| return the empty string, indicating no grouping." Same considerations |
| as for do_decimal_point. |
| </p> |
| |
| <p> |
| i) 22.2.4.1 para. 1 (collate) refers to "instantiations required in Table |
| 51". Same bad jargon. |
| </p> |
| |
| <p> |
| j) 22.2.4.1.2 para. 1 (do_compare) refers to "instantiations required |
| in Table 51". Same bad jargon. |
| </p> |
| |
| <p> |
| k) 22.2.5 para. 1 (time_get/put) uses the same muddled and vacuous |
| as num_get/put. |
| </p> |
| |
| <p> |
| l) 22.2.6 para. 2 (money_get/put) uses the same muddled and vacuous |
| as num_get/put. |
| </p> |
| |
| <p> |
| m) 22.2.6.3.2 (do_pos/neg_format) says "The instantiations required |
| in Table 51 ... return an object of type pattern initialized to |
| {symbol, sign, none, value}." This once again *overrides* the "C" |
| locale, as well as any other locale." |
| </p> |
| |
| <p> |
| 3) We constrain the use_facet calls that can be made by num_get/put, |
| so why don't we do the same for money_get/put? Or for any of the |
| other facets, for that matter? |
| </p> |
| |
| <p> |
| 4) As an almost aside, we spell out when a facet needs to use the ctype |
| facet, but several also need to use a codecvt facet and we don't say so. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <p><i>[ |
| Berlin: Bill to provide wording. |
| ]</i></p> |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| To accompany the concept of a pseudo-random number engine as defined in Table 17, |
| we propose and recommend an adjunct template, engine_traits, to be declared in |
| [tr.rand.synopsis] as: |
| </p> |
| <blockquote><pre>template< class PSRE > |
| class engine_traits; |
| </pre></blockquote> |
| <p> |
| This templateÕs primary purpose would be as an aid to generic programming involving |
| pseudo-random number engines. Given only the facilities described in tr1, it would |
| be very difficult to produce any algorithms involving the notion of a generic engine. |
| The intent of this proposal is to provide, via engine_traits<>, sufficient |
| descriptive information to allow an algorithm to employ a pseudo-random number engine |
| without regard to its exact type, i.e., as a template parameter. |
| </p> |
| <p> |
| For example, today it is not possible to write an efficient generic function that |
| requires any specific number of random bits. More specifically, consider a |
| cryptographic application that internally needs 256 bits of randomness per call: |
| </p> |
| <blockquote><pre>template< class Eng, class InIter, class OutIter > |
| void crypto( Eng& e, InIter in, OutIter out ); |
| </pre></blockquote> |
| <p> |
| Without knowning the number of bits of randomness produced per call to a provided |
| engine, the algorithm has no means of determining how many times to call the engine. |
| </p> |
| <p> |
| In a new section [tr.rand.eng.traits], we proposed to define the engine_traits |
| template as: |
| </p> |
| <blockquote><pre>template< class PSRE > |
| class engine_traits |
| { |
| static std::size_t bits_of_randomness = 0u; |
| static std::string name() { return "unknown_engine"; } |
| // TODO: other traits here |
| }; |
| </pre></blockquote> |
| <p> |
| Further, each engine described in [tr.rand.engine] would be accompanied by a |
| complete specialization of this new engine_traits template. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| </p> |
| |
| <p><i>[ |
| Berlin: Walter: While useful for implementation per TR1, N1932 has no need for this |
| feature. |
| ]</i></p> |
| |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| Issue 371 deals with stability of multiset/multimap under insert and erase |
| (i.e. do they preserve the relative order in ranges of equal elements). |
| The same issue applies to unordered_multiset and unordered_multimap. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[ |
| Moved to open (from review): There is no resolution. |
| ]</i></p> |
| |
| <p> |
| </p> |
| <hr> |
| <a name="522"><h3>522. Tuple doesn't define swap</h3></a><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#Open">Open</a> <b>Submitter:</b> Andy Koenig <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| Tuple doesn't define swap(). It should. |
| </p> |
| <p><i>[ |
| Berlin: Doug to provide wording. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Eric Niebler <b>Date:</b> 1 Jul 2005</p> |
| <p> |
| A problem with TR1 regex is currently being discussed on the Boost |
| developers list. It involves the handling of case-insensitive matching |
| of character ranges such as [Z-a]. The proper behavior (according to the |
| ECMAScript standard) is unimplementable given the current specification |
| of the TR1 regex_traits<> class template. John Maddock, the author of |
| the TR1 regex proposal, agrees there is a problem. The full discussion |
| can be found at http://lists.boost.org/boost/2005/06/28850.php (first |
| message copied below). We don't have any recommendations as yet. |
| </p> |
| <p> |
| -- Begin original message -- |
| </p> |
| <p> |
| The situation of interest is described in the ECMAScript specification |
| (ECMA-262), section 15.10.2.15: |
| </p> |
| <p> |
| "Even if the pattern ignores case, the case of the two ends of a range |
| is significant in determining which characters belong to the range. |
| Thus, for example, the pattern /[E-F]/i matches only the letters E, F, |
| e, and f, while the pattern /[E-f]/i matches all upper and lower-case |
| ASCII letters as well as the symbols [, \, ], ^, _, and `." |
| </p> |
| <p> |
| A more interesting case is what should happen when doing a |
| case-insentitive match on a range such as [Z-a]. It should match z, Z, |
| a, A and the symbols [, \, ], ^, _, and `. This is not what happens with |
| Boost.Regex (it throws an exception from the regex constructor). |
| </p> |
| <p> |
| The tough pill to swallow is that, given the specification in TR1, I |
| don't think there is any effective way to handle this situation. |
| According to the spec, case-insensitivity is handled with |
| regex_traits<>::translate_nocase(CharT) -- two characters are equivalent |
| if they compare equal after both are sent through the translate_nocase |
| function. But I don't see any way of using this translation function to |
| make character ranges case-insensitive. Consider the difficulty of |
| detecting whether "z" is in the range [Z-a]. Applying the transformation |
| to "z" has no effect (it is essentially std::tolower). And we're not |
| allowed to apply the transformation to the ends of the range, because as |
| ECMA-262 says, "the case of the two ends of a range is significant." |
| </p> |
| <p> |
| So AFAICT, TR1 regex is just broken, as is Boost.Regex. One possible fix |
| is to redefine translate_nocase to return a string_type containing all |
| the characters that should compare equal to the specified character. But |
| this function is hard to implement for Unicode, and it doesn't play nice |
| with the existing ctype facet. What a mess! |
| </p> |
| <p> |
| -- End original message -- |
| </p> |
| |
| <p><i>[ |
| John Maddock adds: |
| ]</i></p> |
| |
| <p> |
| One small correction, I have since found that ICU's regex package does |
| implement this correctly, using a similar mechanism to the current |
| TR1.Regex. |
| </p> |
| <p> |
| Given an expression [c1-c2] that is compiled as case insensitive it: |
| </p> |
| <p> |
| Enumerates every character in the range c1 to c2 and converts it to it's |
| case folded equivalent. That case folded character is then used a key to a |
| table of equivalence classes, and each member of the class is added to the |
| list of possible matches supported by the character-class. This second step |
| isn't possible with our current traits class design, but isn't necessary if |
| the input text is also converted to a case-folded equivalent on the fly. |
| </p> |
| <p> |
| ICU applies similar brute force mechanisms to character classes such as |
| [[:lower:]] and [[:word:]], however these are at least cached, so the impact |
| is less noticeable in this case. |
| </p> |
| <p> |
| Quick and dirty performance comparisons show that expressions such as |
| "[X-\\x{fff0}]+" are indeed very slow to compile with ICU (about 200 times |
| slower than a "normal" expression). For an application that uses a lot of |
| regexes this could have a noticeable performance impact. ICU also has an |
| advantage in that it knows the range of valid characters codes: code points |
| outside that range are assumed not to require enumeration, as they can not |
| be part of any equivalence class. I presume that if we want the TR1.Regex |
| to work with arbitrarily large character sets enumeration really does become |
| impractical. |
| </p> |
| <p> |
| Finally note that Unicode has: |
| </p> |
| <p> |
| Three cases (upper, lower and title). |
| One to many, and many to one case transformations. |
| Character that have context sensitive case translations - for example an |
| uppercase sigma has two different lowercase forms - the form chosen depends |
| on context(is it end of a word or not), a caseless match for an upper case |
| sigma should match either of the lower case forms, which is why case folding |
| is often approximated by tolower(toupper(c)). |
| </p> |
| <p> |
| Probably we need some way to enumerate character equivalence classes, |
| including digraphs (either as a result or an input), and some way to tell |
| whether the next character pair is a valid digraph in the current locale. |
| </p> |
| <p> |
| Hoping this doesn't make this even more complex that it was already, |
| </p> |
| |
| <p><i>[ |
| Portland: Alisdair: Detect as invalid, throw an exception. |
| Pete: Possible general problem with case insensitive ranges. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Eric Niebler <b>Date:</b> 1 Jul 2005</p> |
| <p> |
| This defect is also being discussed on the Boost developers list. The |
| full discussion can be found here: |
| http://lists.boost.org/boost/2005/07/29546.php |
| </p> |
| <p> |
| -- Begin original message -- |
| </p> |
| <p> |
| Also, I may have found another issue, closely related to the one under |
| discussion. It regards case-insensitive matching of named character |
| classes. The regex_traits<> provides two functions for working with |
| named char classes: lookup_classname and isctype. To match a char class |
| such as [[:alpha:]], you pass "alpha" to lookup_classname and get a |
| bitmask. Later, you pass a char and the bitmask to isctype and get a |
| bool yes/no answer. |
| </p> |
| <p> |
| But how does case-insensitivity work in this scenario? Suppose we're |
| doing a case-insensitive match on [[:lower:]]. It should behave as if it |
| were [[:lower:][:upper:]], right? But there doesn't seem to be enough |
| smarts in the regex_traits interface to do this. |
| </p> |
| <p> |
| Imagine I write a traits class which recognizes [[:fubar:]], and the |
| "fubar" char class happens to be case-sensitive. How is the regex engine |
| to know that? And how should it do a case-insensitive match of a |
| character against the [[:fubar:]] char class? John, can you confirm this |
| is a legitimate problem? |
| </p> |
| <p> |
| I see two options: |
| </p> |
| <p> |
| 1) Add a bool icase parameter to lookup_classname. Then, |
| lookup_classname( "upper", true ) will know to return lower|upper |
| instead of just upper. |
| </p> |
| <p> |
| 2) Add a isctype_nocase function |
| </p> |
| <p> |
| I prefer (1) because the extra computation happens at the time the |
| pattern is compiled rather than when it is executed. |
| </p> |
| <p> |
| -- End original message -- |
| </p> |
| |
| <p> |
| For what it's worth, John has also expressed his preference for option |
| (1) above. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Robert Klarer <b>Date:</b> 11 Jul 2005</p> |
| <p> |
| It is not completely clear how the primary type traits deal with |
| cv-qualified types. And several of the secondary type traits |
| seem to be lacking a definition. |
| </p> |
| |
| <p><i>[ |
| Berlin: Howard to provide wording. |
| ]</i></p> |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <a name="526"><h3>526. Is it undefined if a function in the standard changes in parameters?</h3></a><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#Open">Open</a> <b>Submitter:</b> Chris Jefferson <b>Date:</b> 14 Sep 2005</p> |
| <p> |
| Problem: There are a number of places in the C++ standard library where |
| it is possible to write what appear to be sensible ways of calling |
| functions, but which can cause problems in some (or all) |
| implementations, as they cause the values given to the function to be |
| changed in a way not specified in standard (and therefore not coded to |
| correctly work). These fall into two similar categories. |
| </p> |
| |
| <p> |
| 1) Parameters taken by const reference can be changed during execution |
| of the function |
| </p> |
| |
| <p> |
| Examples: |
| </p> |
| |
| <p> |
| Given std::vector<int> v: |
| </p> |
| <p> |
| v.insert(v.begin(), v[2]); |
| </p> |
| <p> |
| v[2] can be changed by moving elements of vector |
| </p> |
| |
| |
| <p> |
| Given std::list<int> l: |
| </p> |
| <p> |
| l.remove(*l.begin()); |
| </p> |
| <p> |
| Will delete the first element, and then continue trying to access it. |
| This is particularily vicious, as it will appear to work in almost all |
| cases. |
| </p> |
| |
| <p> |
| 2) A range is given which changes during the execution of the function: |
| Similarly, |
| </p> |
| |
| <p> |
| v.insert(v.begin(), v.begin()+4, v.begin()+6); |
| </p> |
| |
| <p> |
| This kind of problem has been partly covered in some cases. For example |
| std::copy(first, last, result) states that result cannot be in the range |
| [first, last). However, does this cover the case where result is a |
| reverse_iterator built from some iterator in the range [first, last)? |
| Also, std::copy would still break if result was reverse_iterator(last + |
| 1), yet this is not forbidden by the standard |
| </p> |
| |
| <p> |
| Solution: |
| </p> |
| |
| <p> |
| One option would be to try to more carefully limit the requirements of |
| each function. There are many functions which would have to be checked. |
| However as has been shown in the std::copy case, this may be difficult. |
| A simpler, more global option would be to somewhere insert text similar to: |
| </p> |
| |
| <p> |
| If the execution of any function would change either any values passed |
| by reference or any value in any range passed to a function in a way not |
| defined in the definition of that function, the result is undefined. |
| </p> |
| |
| <p> |
| Such code would have to at least cover chapters 23 and 25 (the sections |
| I read through carefully). I can see no harm on applying it to much of |
| the rest of the standard. |
| </p> |
| |
| <p> |
| Some existing parts of the standard could be improved to fit with this, |
| for example the requires for 25.2.1 (Copy) could be adjusted to: |
| </p> |
| |
| <p> |
| Requires: For each non-negative integer n < (last - first), assigning to |
| *(result + n) must not alter any value in the range [first + n, last). |
| </p> |
| |
| <p> |
| However, this may add excessive complication. |
| </p> |
| |
| <p> |
| One other benefit of clearly introducing this text is that it would |
| allow a number of small optimisations, such as caching values passed |
| by const reference. |
| </p> |
| |
| <p> |
| Matt Austern adds that this issue also exists for the <tt>insert</tt> and |
| <tt>erase</tt> members of the ordered and unordered associative containers. |
| </p> |
| |
| <p><i>[ |
| Berlin: Lots of controversey over how this should be solved. Lots of confusion |
| as to whether we're talking about self referencing iterators or references. |
| Needs a good survey as to the cases where this matters, for which |
| implementations, and how expensive it is to fix each case. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="527"></a><h3><a name="527">527. tr1::bind has lost its Throws clause</a></h3><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#Open">Open</a> <b>Submitter:</b> Peter Dimov <b>Date:</b> 01 Oct 2005</p> |
| <p> |
| The original bind proposal gives the guarantee that tr1::bind(f, t1, |
| ..., tN) does not throw when the copy constructors of f, t1, ..., tN |
| don't. |
| </p> |
| |
| <p> |
| This guarantee is not present in the final version of TR1. |
| </p> |
| |
| <p> |
| I'm pretty certain that we never removed it on purpose. Editorial omission? :-) |
| </p> |
| |
| <p><i>[ |
| Berlin: not quite editorial, needs proposed wording. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 20.5.10.1.3 [lib.func.bind.bind] ([tr.func.bind.bind]), add a new paragraph after p2: |
| </p> |
| <blockquote> |
| <i>Throws:</i> Nothing unless one of the copy constructors of <tt>f, t1, t2, ..., tN</tt> |
| throws an exception. |
| </blockquote> |
| |
| <p> |
| Add a new paragraph after p4: |
| </p> |
| <blockquote> |
| <i>Throws:</i> nothing unless one of the copy constructors of <tt>f, t1, t2, ..., tN</tt> |
| throws an exception. |
| </blockquote> |
| <hr> |
| <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#Open">Open</a> <b>Submitter:</b> Paolo Carlini <b>Date:</b> 12 Oct 2005</p> |
| <p> |
| while implementing the resolution of issue 6.19 I'm noticing the |
| following: according to 6.3.4.3/2 (and 6.3.4.5/2), for unordered_set and |
| unordered_multiset: |
| </p> |
| |
| <blockquote> |
| "The iterator and const_iterator types are both const types. It is |
| unspecified whether they are the same type" |
| </blockquote> |
| |
| <p> |
| Now, according to the resolution of 6.19, we have overloads of insert |
| with hint and erase (single and range) both for iterator and |
| const_iterator, which, AFAICS, can be meaningful at the same time *only* |
| if iterator and const_iterator *are* in fact different types. |
| </p> |
| <p> |
| Then, iterator and const_iterator are *required* to be different types? |
| Or that is an unintended consequence? Maybe the overloads for plain |
| iterators should be added only to unordered_map and unordered_multimap? |
| Or, of course, I'm missing something? |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to 6.3.4.3p2 (and 6.3.4.5p2): |
| </p> |
| <p> |
| 2 ... The iterator and const_iterator types are both <del>const</del> |
| <ins>constant</ins> iterator types. |
| It is unspecified whether they are the same type. |
| </p> |
| |
| <p> |
| Add a new subsection to 17.4.4 [lib.conforming]: |
| </p> |
| |
| <blockquote> |
| <p> |
| An implementation shall not supply an overloaded function |
| signature specified in any library clause if such a signature |
| would be inherently ambiguous during overload resolution |
| due to two library types referring to the same type. |
| </p> |
| <p> |
| [Note: For example, this occurs when a container's iterator |
| and const_iterator types are the same. -- end note] |
| </p> |
| </blockquote> |
| |
| <p><i>[ |
| Post-Berlin: Beman supplied wording. |
| ]</i></p> |
| |
| <hr> |
| <a name="529"><h3>529. The standard encourages redundant and confusing preconditions</h3></a><p><b>Section:</b> 17.4.3.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.required"> [lib.res.on.required]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> David Abrahams <b>Date:</b> 25 Oct 2005</p> |
| <p> |
| 17.4.3.8/1 says: |
| </p> |
| |
| <blockquote> |
| Violation of the preconditions specified in a function's |
| Required behavior: paragraph results in undefined behavior unless the |
| function's Throws: paragraph specifies throwing an exception when the |
| precondition is violated. |
| </blockquote> |
| |
| <p> |
| This implies that a precondition violation can lead to defined |
| behavior. That conflicts with the only reasonable definition of |
| precondition: that a violation leads to undefined behavior. Any other |
| definition muddies the waters when it comes to analyzing program |
| correctness, because precondition violations may be routinely done in |
| correct code (e.g. you can use std::vector::at with the full |
| expectation that you'll get an exception when your index is out of |
| range, catch the exception, and continue). Not only is it a bad |
| example to set, but it encourages needless complication and redundancy |
| in the standard. For example: |
| </p> |
| |
| <blockquote><pre> 21 Strings library |
| 21.3.3 basic_string capacity |
| |
| void resize(size_type n, charT c); |
| |
| 5 Requires: n <= max_size() |
| 6 Throws: length_error if n > max_size(). |
| 7 Effects: Alters the length of the string designated by *this as follows: |
| </pre></blockquote> |
| |
| <p> |
| The Requires clause is entirely redundant and can be dropped. We |
| could make that simplifying change (and many others like it) even |
| without changing 17.4.3.8/1; the wording there just seems to encourage |
| the redundant and error-prone Requires: clause. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1. Change 17.4.3.8/1 to read: |
| </p> |
| |
| <blockquote> |
| Violation of the preconditions specified in a function's |
| <i>Required behavior:</i> paragraph results in undefined behavior |
| <del>unless the function's <i>Throws:</i> paragraph specifies throwing |
| an exception when the precondition is violated</del>. |
| </blockquote> |
| |
| <p> |
| 2. Go through and remove redundant Requires: clauses. Specifics to be |
| provided by Dave A. |
| </p> |
| |
| <p><i>[ |
| Berlin: The LWG requests a detailed survey of part 2 of the proposed resolution. |
| ]</i></p> |
| |
| <hr> |
| <a name="531"><h3>531. array forms of unformatted input functions</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#Review">Review</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 23 Nov 2005</p> |
| <p> |
| The array forms of unformatted input functions don't seem to have well-defined |
| semantics for zero-element arrays in a couple of cases. The affected ones |
| (<tt>istream::get()</tt> and <tt>istream::getline()</tt>) are supposed to |
| terminate when <tt>(n - 1)</tt> characters are stored, which obviously can |
| never be true when <tt>(n == 0)</tt> holds to start with. See |
| c++std-lib-16071. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| I suggest changing 27.6.1.3, p7 (<tt>istream::get()</tt>), bullet 1 to read: |
| </p> |
| <p> |
| </p><ul> |
| <li> |
| <tt>(n < 1)</tt> is true or <tt>(n - 1)</tt> characters |
| are stored; |
| </li> |
| </ul> |
| <p></p> |
| <p> |
| Change 27.6.1.3, p9: |
| </p> |
| |
| <blockquote> |
| If the function stores no characters, it calls <tt>setstate(failbit)</tt> (which |
| may throw <tt>ios_base::failure</tt> (27.4.4.3)). In any case, <ins>if <tt>(n |
| > 0)</tt> is true</ins> it then stores a null character into the next |
| successive location of the array. |
| </blockquote> |
| |
| <p> |
| |
| and similarly p17 (<tt>istream::getline()</tt>), bullet 3 to: |
| |
| </p> |
| <p> |
| </p><ul> |
| <li> |
| <tt>(n < 1)</tt> is true or <tt>(n - 1)</tt> characters |
| are stored (in which case the function calls |
| <tt>setstate(failbit)</tt>). |
| </li> |
| </ul> |
| <p></p> |
| |
| <p> |
| |
| In addition, to clarify that <tt>istream::getline()</tt> must not store the |
| terminating NUL character unless the the array has non-zero size, Robert |
| Klarer suggests in c++std-lib-16082 to change 27.6.1.3, p20 to read: |
| |
| </p> |
| <p> |
| </p><blockquote> |
| |
| In any case, provided <tt>(n > 0)</tt> is true, it then stores a null character |
| (using charT()) into the next successive location of the array. |
| |
| </blockquote> |
| <p></p> |
| |
| <p><i>[ |
| post-Redmond: Pete noticed that the current resolution for <tt>get</tt> requires |
| writing to out of bounds memory when <tt>n == 0</tt>. Martin provided fix. |
| ]</i></p> |
| |
| <hr> |
| <a name="532"><h3>532. Tuple comparison</h3></a><p><b>Section:</b> TR1 6.1.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.tuple.rel"> [tr.tuple.rel]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> David Abrahams <b>Date:</b> 29 Nov 2005</p> |
| <p> |
| Where possible, tuple comparison operators <,<=,=>, and > ought to be |
| defined in terms of std::less rather than operator<, in order to |
| support comparison of tuples of pointers. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| change 6.1.3.5/5 from: |
| </p> |
| |
| <blockquote> |
| Returns: The result of a lexicographical comparison between t and |
| u. The result is defined as: (bool)(get<0>(t) < get<0>(u)) || |
| (!(bool)(get<0>(u) < get<0>(t)) && ttail < utail), where rtail for |
| some tuple r is a tuple containing all but the first element of |
| r. For any two zero-length tuples e and f, e < f returns false. |
| </blockquote> |
| |
| <p> |
| to: |
| </p> |
| |
| <blockquote> |
| <p> |
| Returns: The result of a lexicographical comparison between t and |
| u. For any two zero-length tuples e and f, e < f returns false. |
| Otherwise, the result is defined as: cmp( get<0>(t), get<0>(u)) || |
| (!cmp(get<0>(u), get<0>(t)) && ttail < utail), where rtail for some |
| tuple r is a tuple containing all but the first element of r, and |
| cmp(x,y) is an unspecified function template defined as follows. |
| </p> |
| <p> |
| Where T is the type of x and U is the type of y: |
| </p> |
| |
| <p> |
| if T and U are pointer types and T is convertible to U, returns |
| less<U>()(x,y) |
| </p> |
| |
| <p> |
| otherwise, if T and U are pointer types, returns less<T>()(x,y) |
| </p> |
| |
| <p> |
| otherwise, returns (bool)(x < y) |
| </p> |
| </blockquote> |
| |
| <p><i>[ |
| Berlin: This issue is much bigger than just tuple (pair, containers, |
| algorithms). Dietmar will survey and work up proposed wording. |
| ]</i></p> |
| |
| <hr> |
| <a name="534"><h3>534. Missing basic_string members</h3></a><p><b>Section:</b> 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Review">Review</a> <b>Submitter:</b> Alisdair Meredith <b>Date:</b> 16 Nov 2005</p> |
| <p> |
| OK, we all know std::basic_string is bloated and already has way too |
| many members. However, I propose it is missing 3 useful members that |
| are often expected by users believing it is a close approximation of the |
| container concept. All 3 are listed in table 71 as 'optional' |
| </p> |
| |
| <p> |
| i/ pop_back. |
| </p> |
| |
| <p> |
| This is the one I feel most strongly about, as I only just discovered it |
| was missing as we are switching to a more conforming standard library |
| <g> |
| </p> |
| |
| <p> |
| I find it particularly inconsistent to support push_back, but not |
| pop_back. |
| </p> |
| |
| <p> |
| ii/ back. |
| </p> |
| |
| <p> |
| There are certainly cases where I want to examine the last character of |
| a string before deciding to append, or to trim trailing path separators |
| from directory names etc. *rbegin() somehow feels inelegant. |
| </p> |
| |
| <p> |
| iii/ front |
| </p> |
| |
| <p> |
| This one I don't feel strongly about, but if I can get the first two, |
| this one feels that it should be added as a 'me too' for consistency. |
| </p> |
| |
| <p> |
| I believe this would be similarly useful to the data() member recently |
| added to vector, or at() member added to the maps. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the following members to definition of class template basic_string, 21.3p7 |
| </p> |
| <blockquote><pre>void pop_back () |
| |
| const charT & front() const |
| charT & front() |
| |
| const charT & back() const |
| charT & back() |
| </pre></blockquote> |
| <p> |
| Add the following paragraphs to basic_string description |
| </p> |
| |
| <p> |
| 21.3.4p5 |
| </p> |
| <blockquote> |
| <pre>const charT & front() const |
| charT & front() |
| </pre> |
| <p> |
| <i>Precondition:</i> <tt>!empty()</tt> |
| </p> |
| <p> |
| <i>Effects:</i> Equivalent to <tt>operator[](0)</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| 21.3.4p6 |
| </p> |
| <blockquote> |
| <pre>const charT & back() const |
| charT & back() |
| </pre> |
| <p> |
| <i>Precondition:</i> <tt>!empty()</tt> |
| </p> |
| <p> |
| <i>Effects:</i> Equivalent to <tt>operator[]( size() - 1)</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| 21.3.5.5p10 |
| </p> |
| <blockquote> |
| <pre>void pop_back () |
| </pre> |
| <p> |
| <i>Precondition:</i> <tt>!empty()</tt> |
| </p> |
| <p> |
| <i>Effects:</i> Equivalent to <tt>erase( size() - 1, 1 )</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| Update Table 71: (optional sequence operations) |
| Add basic_string to the list of containers for the following operations. |
| </p> |
| <blockquote><pre>a.front() |
| a.back() |
| a.push_back() |
| a.pop_back() |
| a[n] |
| </pre></blockquote> |
| |
| <p><i>[ |
| Berlin: Has support. Alisdair provided wording. |
| ]</i></p> |
| <hr> |
| <a name="536"><h3>536. Container iterator constructor and explicit convertibility</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> JoaquÃn M López Muñoz <b>Date:</b> 17 Dec 2005</p> |
| <p> |
| The iterator constructor X(i,j) for containers as defined in 23.1.1 and |
| 23.2.2 does only require that i and j be input iterators but |
| nothing is said about their associated value_type. There are three |
| sensible |
| options: |
| </p> |
| <ol> |
| <li>iterator's value_type is exactly X::value_type (modulo cv).</li> |
| <li>iterator's value_type is *implicitly* convertible to X::value_type.</li> |
| <li>iterator's value_type is *explicitly* convertible to X::value_type.</li> |
| </ol> |
| <p> |
| The issue has practical implications, and stdlib vendors have |
| taken divergent approaches to it: Dinkumware follows 2, |
| libstdc++ follows 3. |
| </p> |
| <p> |
| The same problem applies to the definition of insert(p,i,j) for |
| sequences and insert(i,j) for associative contianers, as well as |
| assign. |
| </p> |
| |
| <p><i>[ |
| The following added by Howard and the example code was originally written by |
| Dietmar. |
| ]</i></p> |
| <p> |
| Valid code below? |
| </p> |
| |
| <blockquote><pre>#include <vector> |
| #include <iterator> |
| #include <iostream> |
| |
| struct foo |
| { |
| explicit foo(int) {} |
| }; |
| |
| int main() |
| { |
| std::vector<int> v_int; |
| std::vector<foo> v_foo1(v_int.begin(), v_int.end()); |
| std::vector<foo> v_foo2((std::istream_iterator<int>(std::cin)), |
| std::istream_iterator<int>()); |
| } |
| </pre></blockquote> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <p><i>[ |
| Berlin: Some support, not universal, for respecting the explicit qualifier. |
| ]</i></p> |
| <hr> |
| <a name="539"><h3>539. partial_sum and adjacent_difference should mention requirements</h3></a><p><b>Section:</b> 26.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.rand"> [lib.rand]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Marc Schoolderman <b>Date:</b> 6 Feb 2006</p> |
| <p> |
| There are some problems in the definition of partial_sum and |
| adjacent_difference in 26.4 [lib.numeric.ops] |
| </p> |
| |
| <p> |
| Unlike <tt>accumulate</tt> and <tt>inner_product</tt>, these functions are not |
| parametrized on a "type T", instead, 26.4.3 [lib.partial.sum] simply |
| specifies the effects clause as; |
| </p> |
| |
| <blockquote> |
| Assigns to every element referred to by iterator <tt>i</tt> in the range |
| <tt>[result,result + (last - first))</tt> a value correspondingly equal to |
| <blockquote><pre>((...(* first + *( first + 1)) + ...) + *( first + ( i - result ))) |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| And similarly for BinaryOperation. Using just this definition, it seems |
| logical to expect that: |
| </p> |
| |
| |
| <blockquote><pre>char i_array[4] = { 100, 100, 100, 100 }; |
| int o_array[4]; |
| |
| std::partial_sum(i_array, i_array+4, o_array); |
| </pre></blockquote> |
| |
| <p> |
| Is equivalent to |
| </p> |
| |
| <blockquote><pre>int o_array[4] = { 100, 100+100, 100+100+100, 100+100+100+100 }; |
| </pre></blockquote> |
| |
| <p> |
| i.e. 100, 200, 300, 400, with addition happening in the <tt>result type</tt>, |
| <tt>int</tt>. |
| </p> |
| |
| <p> |
| Yet all implementations I have tested produce 100, -56, 44, -112, |
| because they are using an accumulator of the <tt>InputIterator</tt>'s |
| <tt>value_type</tt>, which in this case is <tt>char</tt>, not <tt>int</tt>. |
| </p> |
| |
| <p> |
| The issue becomes more noticeable when the result of the expression <tt>*i + |
| *(i+1)</tt> or <tt>binary_op(*i, *i-1)</tt> can't be converted to the |
| <tt>value_type</tt>. In a contrived example: |
| </p> |
| |
| <blockquote><pre>enum not_int { x = 1, y = 2 }; |
| ... |
| not_int e_array[4] = { x, x, y, y }; |
| std::partial_sum(e_array, e_array+4, o_array); |
| </pre></blockquote> |
| |
| <p> |
| Is it the intent that the operations happen in the <tt>input type</tt>, or in |
| the <tt>result type</tt>? |
| </p> |
| |
| <p> |
| If the intent is that operations happen in the <tt>result type</tt>, something |
| like this should be added to the "Requires" clause of 26.4.3/4 |
| [lib.partial.sum]: |
| </p> |
| |
| <blockquote> |
| The type of <tt>*i + *(i+1)</tt> or <tt>binary_op(*i, *(i+1))</tt> shall meet the |
| requirements of <tt>CopyConstructible</tt> (20.1.3) and <tt>Assignable</tt> |
| (23.1) types. |
| </blockquote> |
| |
| <p> |
| (As also required for <tt>T</tt> in 26.4.1 [lib.accumulate] and 26.4.2 |
| [lib.inner.product].) |
| </p> |
| |
| <p> |
| The "auto initializer" feature proposed in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1894.pdf">N1894</a> |
| is not required to |
| implement <tt>partial_sum</tt> this way. The 'narrowing' behaviour can still be |
| obtained by using the <tt>std::plus<></tt> function object. |
| </p> |
| |
| <p> |
| If the intent is that operations happen in the <tt>input type</tt>, then |
| something like this should be added instead; |
| </p> |
| |
| <blockquote> |
| The type of *first shall meet the requirements of |
| <tt>CopyConstructible</tt> (20.1.3) and <tt>Assignable</tt> (23.1) types. |
| The result of <tt>*i + *(i+1)</tt> or <tt>binary_op(*i, *(i+1))</tt> shall be |
| convertible to this type. |
| </blockquote> |
| |
| <p> |
| The 'widening' behaviour can then be obtained by writing a custom proxy |
| iterator, which is somewhat involved. |
| </p> |
| |
| <p> |
| In both cases, the semantics should probably be clarified. |
| </p> |
| |
| <p> |
| 26.4.4 [lib.adjacent.difference] is similarly underspecified, although |
| all implementations seem to perform operations in the 'result' type: |
| </p> |
| |
| <blockquote><pre>unsigned char i_array[4] = { 4, 3, 2, 1 }; |
| int o_array[4]; |
| |
| std::adjacent_difference(i_array, i_array+4, o_array); |
| </pre></blockquote> |
| |
| <p> |
| o_array is 4, -1, -1, -1 as expected, not 4, 255, 255, 255. |
| </p> |
| |
| <p> |
| In any case, <tt>adjacent_difference</tt> doesn't mention the requirements on the |
| <tt>value_type</tt>; it can be brought in line with the rest of 26.4 |
| [lib.numeric.ops] by adding the following to 26.4.4/2 |
| [lib.adjacent.difference]: |
| </p> |
| |
| <blockquote> |
| The type of <tt>*first</tt> shall meet the requirements of |
| <tt>CopyConstructible</tt> (20.1.3) and <tt>Assignable</tt> (23.1) types." |
| </blockquote> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <p><i>[ |
| Berlin: Giving output iterator's value_types very controversial. Suggestion of |
| adding signatures to allow user to specify "accumulator". |
| ]</i></p> |
| <hr> |
| <a name="542"><h3>542. shared_ptr observers</h3></a><p><b>Section:</b> TR1 2.2.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.util.smartptr.shared.obs"> [tr.util.smartptr.shared.obs]</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 Oct 2005</p> |
| <p> |
| Peter Dimov wrote: |
| To: C++ libraries mailing list |
| Message c++std-lib-15614 |
| [...] |
| The intent is for both use_count() and unique() to work in a threaded environment. |
| They are intrinsically prone to race conditions, but they never return garbage. |
| </p> |
| |
| <p> |
| This is a crucial piece of information that I really wish were |
| captured in the text. Having this in a non-normative note would |
| have made everything crystal clear to me and probably stopped |
| me from ever starting this discussion :) Instead, the sentence |
| in p12 "use only for debugging and testing purposes, not for |
| production code" very strongly suggests that implementations |
| can and even are encouraged to return garbage (when threads |
| are involved) for performance reasons. |
| </p> |
| <p> |
| How about adding an informative note along these lines: |
| </p> |
| <blockquote> |
| Note: Implementations are encouraged to provide well-defined |
| behavior for use_count() and unique() even in the presence of |
| multiple threads. |
| </blockquote> |
| <p> |
| I don't necessarily insist on the exact wording, just that we |
| capture the intent. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="543"><h3>543. valarray slice default constructor</h3></a><p><b>Section:</b> 26.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.members"> [lib.complex.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> Howard Hinnant <b>Date:</b> 3 Nov 2005</p> |
| <p> |
| If one explicitly constructs a slice or glice with the default |
| constructor, does the standard require this slice to have any usable |
| state? It says "creates a slice which specifies no elements", which |
| could be interpreted two ways: |
| </p> |
| <ol> |
| <li>There are no elements to which the slice refers (i.e. undefined).</li> |
| <li>The slice specifies an array with no elements in it (i.e. defined).</li> |
| </ol> |
| <p> |
| Here is a bit of code to illustrate: |
| </p> |
| <blockquote><pre>#include <iostream> |
| #include <valarray> |
| |
| int main() |
| { |
| std::valarray<int> v(10); |
| std::valarray<int> v2 = v[std::slice()]; |
| std::cout << "v[slice()].size() = " << v2.size() << '\n'; |
| } |
| </pre></blockquote> |
| |
| <p> |
| Is the behavior undefined? Or should the output be: |
| </p> |
| |
| <blockquote> |
| v[slice()].size() = 0 |
| </blockquote> |
| |
| <p> |
| There is a similar question and wording for gslice at 26.3.6.1p1. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 26.5.4.1 [cons.slice]: |
| </p> |
| |
| <blockquote> |
| 1 - <del>The default constructor for <tt>slice</tt> creates a <tt>slice</tt> |
| which specifies no elements.</del> <ins>The default constructor is equivalent to |
| <tt>slice(0, 0, 0)</tt>.</ins> A default constructor is provided only to permit |
| the declaration of arrays of slices. The constructor with arguments for a slice |
| takes a start, length, and stride parameter. |
| </blockquote> |
| |
| <p> |
| Change 26.3.6.1 [gslice.cons]: |
| </p> |
| |
| <blockquote> |
| 1 - <del>The default constructor creates a <tt>gslice</tt> which specifies no |
| elements.</del> <ins>The default constructor is equivalent to <tt>gslice(0, |
| valarray<size_t>(), valarray<size_t>())</tt>.</ins> The constructor |
| with arguments builds a <tt>gslice</tt> based on a specification of start, |
| lengths, and strides, as explained in the previous section. |
| </blockquote> |
| |
| <hr> |
| <a name="545"><h3>545. When is a deleter deleted?</h3></a><p><b>Section:</b> TR1 2.2.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.util.smartptr.shared.dest"> [tr.util.smartptr.shared.dest]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 10 Jan 2006</p> |
| <p> |
| The description of ~shared_ptr doesn't say when the shared_ptr's deleter, if |
| any, is destroyed. In principle there are two possibilities: it is destroyed |
| unconditionally whenever ~shared_ptr is executed (which, from an implementation |
| standpoint, means that the deleter is copied whenever the shared_ptr is copied), |
| or it is destroyed immediately after the owned pointer is destroyed (which, from |
| an implementation standpoint, means that the deleter object is shared between |
| instances). We should say which it is. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add after the first sentence of [lib.util.smartptr.getdeleter]/1: |
| </p> |
| <blockquote> |
| <p> |
| The returned pointer remains valid as long as there exists a <tt>shared_ptr</tt> instance |
| that owns <tt><i>d</i></tt>. |
| </p> |
| <p> |
| [<i>Note:</i> it is unspecified whether the pointer remains valid longer than that. |
| This can happen if the implementation doesn't destroy the deleter until all |
| <tt>weak_ptr</tt> instances in the ownership group are destroyed. <i>-- end note</i>] |
| </p> |
| </blockquote> |
| <hr> |
| <a name="546"><h3>546. _Longlong and _ULonglong are integer types</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> Matt Austern <b>Date:</b> 10 Jan 2006</p> |
| <p> |
| The TR sneaks in two new integer types, _Longlong and _Ulonglong, in [tr.c99]. |
| The rest of the TR should use that type. I believe this affects two places. |
| First, the random number requirements, 5.1.1/10-11, lists all of the types with |
| which template parameters named IntType and UIntType may be instantiated. |
| _Longlong (or "long long", assuming it is added to C++0x) should be added to the |
| IntType list, and UIntType (again, or "unsigned long long") should be added to |
| the UIntType list. Second, 6.3.2 lists the types for which hash<> is |
| required to be instantiable. _Longlong and _Ulonglong should be added to that |
| list, so that people may use long long as a hash key. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="547"><h3>547. division should be floating-point, not integer</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#New">New</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 10 Jan 2006</p> |
| <p> |
| Paragraph 10 describes how a variate generator uses numbers produced by an |
| engine to pass to a generator. The sentence that concerns me is: "Otherwise, if |
| the value for engine_value_type::result_type is true and the value for |
| Distribution::input_type is false [i.e. if the engine produces integers and the |
| engine wants floating-point values], then the numbers in s_eng are divided by |
| engine().max() - engine().min() + 1 to obtain the numbers in s_e." Since the |
| engine is producing integers, both the numerator and the denominator are |
| integers and we'll be doing integer division, which I don't think is what we |
| want. Shouldn't we be performing a conversion to a floating-point type first? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="548"><h3>548. May random_device block?</h3></a><p><b>Section:</b> TR1 5.1.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.device"> [tr.rand.device]</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> 10 Jan 2006</p> |
| <p> |
| Class random_device "produces non-deterministic random numbers", using some |
| external source of entropy. In most real-world systems, the amount of available |
| entropy is limited. Suppose that entropy has been exhausted. What is an |
| implementation permitted to do? In particular, is it permitted to block |
| indefinitely until more random bits are available, or is the implementation |
| required to detect failure immediately? This is not an academic question. On |
| Linux a straightforward implementation would read from /dev/random, and "When |
| the entropy pool is empty, reads to /dev/random will block until additional |
| environmental noise is gathered." Programmers need to know whether random_device |
| is permitted to (or possibly even required to?) behave the same way. |
| </p> |
| |
| <p><i>[ |
| Berlin: Walter: N1932 considers this NAD. Does the standard specify whether std::cin |
| may block? |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="550"><h3>550. What should the return type of pow(float,int) be?</h3></a><p><b>Section:</b> 26.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.numarray"> [lib.numarray]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 12 Jan 2006</p> |
| <p> |
| Assuming we adopt the |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C |
| compatibility package from C99</a> what should be the return type of the |
| following signature be: |
| </p> |
| <blockquote><pre>? pow(float, int); |
| </pre></blockquote> |
| <p> |
| C++03 says that the return type should be <tt>float</tt>. |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf"> |
| TR1</a> and C90/99 say the return type should be <tt>double</tt>. This can put |
| clients into a situation where C++03 provides answers that are not as high |
| quality as C90/C99/TR1. For example: |
| </p> |
| <blockquote><pre>#include <math.h> |
| |
| int main() |
| { |
| float x = 2080703.375F; |
| double y = pow(x, 2); |
| } |
| </pre></blockquote> |
| <p> |
| Assuming an IEEE 32 bit float and IEEE 64 bit double, C90/C99/TR1 all suggest: |
| </p> |
| |
| <blockquote><pre>y = 4329326534736.390625 |
| </pre></blockquote> |
| |
| <p> |
| which is exactly right. While C++98/C++03 demands: |
| </p> |
| |
| <blockquote><pre>y = 4329326510080. |
| </pre></blockquote> |
| |
| <p> |
| which is only approximately right. |
| </p> |
| |
| <p> |
| I recommend that C++0X adopt the mixed mode arithmetic already adopted by |
| Fortran, C and TR1 and make the return type of <tt>pow(float,int)</tt> be |
| <tt>double</tt>. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="551"></a><h3><a name="551">551. <ccomplex></a></h3><p><b>Section:</b> TR1 8.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.c99.ccmplx"> [tr.c99.ccmplx]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Review">Review</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 23 Jan 2006</p> |
| <p> |
| Previously xxx.h was parsable by C++. But in the case of C99's <complex.h> |
| it isn't. Otherwise we could model it just like <string.h>, <cstring>, <string>: |
| </p> |
| |
| <ul> |
| <li><string> : C++ API in namespace std</li> |
| <li><cstring> : C API in namespace std</li> |
| <li><string.h> : C API in global namespace</li> |
| </ul> |
| |
| <p> |
| In the case of C's complex, the C API won't compile in C++. So we have: |
| </p> |
| |
| <ul> |
| <li><complex> : C++ API in namespace std</li> |
| <li><ccomplex> : ?</li> |
| <li><complex.h> : ?</li> |
| </ul> |
| |
| <p> |
| The ? can't refer to the C API. TR1 currently says: |
| </p> |
| |
| <ul> |
| <li><complex> : C++ API in namespace std</li> |
| <li><ccomplex> : C++ API in namespace std</li> |
| <li><complex.h> : C++ API in global namespace</li> |
| </ul> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 26.3.11 [cmplxh]: |
| </p> |
| |
| <blockquote> |
| <p> |
| The header behaves as if it includes the header |
| <tt><ccomplex></tt><ins>.</ins><del>, and provides sufficient using |
| declarations to declare in the global namespace all function and type names |
| declared or defined in the neader <tt><complex></tt>.</del> |
| <ins>[<i>Note:</i> <tt><complex.h></tt> does not promote any interface |
| into the global namespace as there is no C interface to promote. <i>--end |
| note</i>]</ins> |
| </p> |
| </blockquote> |
| |
| <hr> |
| <a name="552"><h3>552. random_shuffle and its generator</h3></a><p><b>Section:</b> 25.2.11 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.random.shuffle"> [lib.alg.random.shuffle]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 25 Jan 2006</p> |
| <p> |
| ...is specified to shuffle its range by calling swap but not how |
| (or even that) it's supposed to use the RandomNumberGenerator |
| argument passed to it. |
| </p> |
| <p> |
| Shouldn't we require that the generator object actually be used |
| by the algorithm to obtain a series of random numbers and specify |
| how many times its operator() should be invoked by the algorithm? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="553"><h3>553. very minor editorial change intptr_t / uintptr_t</h3></a><p><b>Section:</b> TR1 8.22.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.c99.cstdint.syn"> [tr.c99.cstdint.syn]</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> 30 Jan 2006</p> |
| <p> |
| In the synopsis, some types are identified as optional: int8_t, int16_t, |
| and so on, consistently with C99, indeed. |
| </p> |
| <p> |
| On the other hand, intptr_t and uintptr_t, are not marked as such and |
| probably should, consistently with C99, 7.18.1.4. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="556"><h3>556. is Compare a BinaryPredicate?</h3></a><p><b>Section:</b> 25.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.sorting"> [lib.alg.sorting]</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 Feb 2006</p> |
| <p> |
| In 25, p8 we allow BinaryPredicates to return a type that's convertible |
| to bool but need not actually be bool. That allows predicates to return |
| things like proxies and requires that implementations be careful about |
| what kinds of expressions they use the result of the predicate in (e.g., |
| the expression in if (!pred(a, b)) need not be well-formed since the |
| negation operator may be inaccessible or return a type that's not |
| convertible to bool). |
| </p> |
| <p> |
| Here's the text for reference: |
| </p> |
| <blockquote> |
| ...if an algorithm takes BinaryPredicate binary_pred as its argument |
| and first1 and first2 as its iterator arguments, it should work |
| correctly in the construct if (binary_pred(*first1, first2)){...}. |
| </blockquote> |
| |
| <p> |
| In 25.3, p2 we require that the Compare function object return true |
| of false, which would seem to preclude such proxies. The relevant text |
| is here: |
| </p> |
| <blockquote> |
| Compare is used as a function object which returns true if the first |
| argument is less than the second, and false otherwise... |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| I think we could fix this by rewording 25.3, p2 to read somthing like: |
| </p> |
| <blockquote> |
| -2- <tt>Compare</tt> is <del>used as a function object which returns |
| <tt>true</tt> if the first argument</del> <ins>a <tt>BinaryPredicate</tt>. The |
| return value of the function call operator applied to an object of type |
| <tt>Compare</tt>, when converted to type <tt>bool</tt>, yields <tt>true</tt> |
| if the first argument of the call</ins> is less than the second, and |
| <tt>false</tt> otherwise. <tt>Compare <i>comp</i></tt> is used throughout for |
| algorithms assuming an ordering relation. It is assumed that <tt><i>comp</i></tt> |
| will not apply any non-constant function through the dereferenced iterator. |
| </blockquote> |
| <hr> |
| <a name="557"><h3>557. TR1: div(_Longlong, _Longlong) vs div(intmax_t, intmax_t)</h3></a><p><b>Section:</b> TR1 8.11.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.c99.cinttypes.syn"> [tr.c99.cinttypes.syn]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Paolo Carlini <b>Date:</b> 6 Feb 2006</p> |
| <p> |
| I'm seeing a problem with such overloads: when, _Longlong == intmax_t == |
| long long we end up, essentially, with the same arguments and different |
| return types (lldiv_t and imaxdiv_t, respectively). Similar issue with |
| abs(_Longlong) and abs(intmax_t), of course. |
| </p> |
| <p> |
| Comparing sections 8.25 and 8.11, I see an important difference, |
| however: 8.25.3 and 8.25.4 carefully describe div and abs for _Longlong |
| types (rightfully, because not moved over directly from C99), whereas |
| there is no equivalent in 8.11: the abs and div overloads for intmax_t |
| types appear only in the synopsis and are not described anywhere, in |
| particular no mention in 8.11.2 (at variance with 8.25.2). |
| </p> |
| <p> |
| I'm wondering whether we really, really, want div and abs for intmax_t... |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the <tt><cstdint></tt> synopsis in 8.11.1: |
| </p> |
| <blockquote><pre>... |
| intmax_t imaxabs(intmax_t i); |
| <del>intmax_t abs(intmax_t i);</del> |
| |
| imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); |
| <del>imaxdiv_t div(intmax_t numer, intmax_t denom);</del> |
| ... |
| </pre></blockquote> |
| |
| <p><i>[ |
| Portland: no consensus. |
| ]</i></p> |
| |
| <hr> |
| <a name="559"><h3>559. numeric_limits<const T></h3></a><p><b>Section:</b> 18.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.support.limits"> [lib.support.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> 19 Feb 2006</p> |
| <p> |
| |
| 18.2.1, p2 requires implementations to provide specializations of the |
| <code>numeric_limits</code> template for each scalar type. While this |
| could be interepreted to include cv-qualified forms of such types such |
| an interepretation is not reflected in the synopsis of the |
| <code><limits></code> header. |
| |
| </p> |
| <p> |
| |
| The absence of specializations of the template on cv-qualified forms |
| of fundamental types makes <code>numeric_limits</code> difficult to |
| use in generic code where the constness (or volatility) of a type is |
| not always immediately apparent. In such contexts, the primary |
| template ends up being instantiated instead of the provided |
| specialization, typically yielding unexpected behavior. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Require that specializations of <code>numeric_limits</code> on |
| cv-qualified fundamental types have the same semantics as those on the |
| unqualifed forms of the same types. |
| |
| </p> |
| <p> |
| |
| Add to the synopsis of the <code><limits></code> header, |
| immediately below the declaration of the primary template, the |
| following: |
| |
| </p><pre> |
| template <class T> class numeric_limits<const T>; |
| template <class T> class numeric_limits<volatile T>; |
| template <class T> class numeric_limits<const volatile T>; |
| |
| </pre> |
| |
| <p></p> |
| <p> |
| |
| Add a new paragraph to the end of 18.2.1.1, with the following |
| text: |
| |
| </p> |
| <p> |
| |
| -new-para- The value of each member of a <code>numeric_limits</code> |
| specialization on a cv-qualified T is equal to the value of the same |
| member of <code>numeric_limits<T></code>. |
| |
| </p> |
| |
| <p><i>[ |
| Portland: Martin will clarify that user-defined types get cv-specializations |
| automatically. |
| ]</i></p> |
| |
| <hr> |
| <a name="560"><h3>560. User-defined allocators without default constructor</h3></a><p><b>Section:</b> 20.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.default.con.req"> [lib.default.con.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> Sergey P. Derevyago <b>Date:</b> 17 Feb 2006</p> |
| <h4>1. The essence of the problem.</h4> |
| <p> |
| User-defined allocators without default constructor are not explicitly |
| supported by the standard but they can be supported just like std::vector |
| supports elements without default constructor. |
| </p> |
| <p> |
| As a result, there exist implementations that work well with such allocators |
| and implementations that don't. |
| </p> |
| |
| <h4>2. The cause of the problem.</h4> |
| <p> |
| 1) The standard doesn't explicitly state this intent but it should. In |
| particular, 20.1.5p5 explicitly state the intent w.r.t. the allocator |
| instances that compare non-equal. So it can similarly state the intent w.r.t. |
| the user-defined allocators without default constructor. |
| </p> |
| <p> |
| 2) Some container operations are obviously underspecified. In particular, |
| 21.3.7.1p2 tells: |
| </p> |
| <blockquote> |
| <pre>template<class charT, class traits, class Allocator> |
| basic_string<charT,traits,Allocator> operator+( |
| const charT* lhs, |
| const basic_string<charT,traits,Allocator>& rhs |
| ); |
| </pre> |
| Returns: <tt>basic_string<charT,traits,Allocator>(lhs) + rhs</tt>. |
| </blockquote> |
| <p> |
| That leads to the basic_string<charT,traits,Allocator>(lhs, Allocator()) call. |
| Obviously, the right requirement is: |
| </p> |
| <blockquote> |
| Returns: <tt>basic_string<charT,traits,Allocator>(lhs, rhs.get_allocator()) + rhs</tt>. |
| </blockquote> |
| <p> |
| It seems like a lot of DRs can be submitted on this "Absent call to |
| get_allocator()" topic. |
| </p> |
| |
| <h4>3. Proposed actions.</h4> |
| <p> |
| 1) Explicitly state the intent to allow for user-defined allocators without |
| default constructor in 20.1.5 Allocator requirements. |
| </p> |
| <p> |
| 2) Correct all the places, where a correct allocator object is available |
| through the get_allocator() call but default Allocator() gets passed instead. |
| </p> |
| <h4>4. Code sample.</h4> |
| <p> |
| Let's suppose that the following memory pool is available: |
| </p> |
| <blockquote><pre>class mem_pool { |
| // ... |
| void* allocate(size_t size); |
| void deallocate(void* ptr, size_t size); |
| }; |
| </pre></blockquote> |
| <p> |
| So the following allocator can be implemented via this pool: |
| </p> |
| <blockquote><pre>class stl_allocator { |
| mem_pool& pool; |
| |
| public: |
| explicit stl_allocator(mem_pool& mp) : pool(mp) {} |
| stl_allocator(const stl_allocator& sa) : pool(sa.pool) {} |
| template <class U> |
| stl_allocator(const stl_allocator<U>& sa) : pool(sa.get_pool()) {} |
| ~stl_allocator() {} |
| |
| pointer allocate(size_type n, std::allocator<void>::const_pointer = 0) |
| { |
| return (n!=0) ? static_cast<pointer>(pool.allocate(n*sizeof(T))) : 0; |
| } |
| |
| void deallocate(pointer p, size_type n) |
| { |
| if (n!=0) pool.deallocate(p, n*sizeof(T)); |
| } |
| |
| // ... |
| }; |
| </pre></blockquote> |
| <p> |
| Then the following code works well on some implementations and doesn't work on |
| another: |
| </p> |
| <blockquote><pre>typedef basic_string<char, char_traits<char>, stl_allocator<char> > |
| tl_string; |
| mem_pool mp; |
| tl_string s1("abc", stl_allocator<int>(mp)); |
| printf("(%s)\n", ("def"+s1).c_str()); |
| </pre></blockquote> |
| <p> |
| In particular, on some implementations the code can't be compiled without |
| default stl_allocator() constructor. |
| </p> |
| <p> |
| The obvious way to solve the compile-time problems is to intentionally define |
| a NULL pointer dereferencing default constructor |
| </p> |
| <blockquote><pre>stl_allocator() : pool(*static_cast<mem_pool*>(0)) {} |
| </pre></blockquote> |
| <p> |
| in a hope that it will not be called. The problem is that it really gets |
| called by operator+(const char*, const string&) under the current 21.3.7.1p2 |
| wording. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="561"><h3>561. inserter overly generic</h3></a><p><b>Section:</b> 24.4.2.6.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.inserter"> [lib.inserter]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 21 Feb 2006</p> |
| <p> |
| The declaration of <tt>std::inserter</tt> is: |
| </p> |
| |
| <blockquote><pre>template <class Container, class Iterator> |
| insert_iterator<Container> |
| inserter(Container& x, Iterator i); |
| </pre></blockquote> |
| |
| <p> |
| The template parameter <tt>Iterator</tt> in this function is completely unrelated |
| to the template parameter <tt>Container</tt> when it doesn't need to be. This |
| causes the code to be overly generic. That is, any type at all can be deduced |
| as <tt>Iterator</tt>, whether or not it makes sense. Now the same is true of |
| <tt>Container</tt>. However, for every free (unconstrained) template parameter |
| one has in a signature, the opportunity for a mistaken binding grows geometrically. |
| </p> |
| |
| <p> |
| It would be much better if <tt>inserter</tt> had the following signature instead: |
| </p> |
| |
| <blockquote><pre>template <class Container> |
| insert_iterator<Container> |
| inserter(Container& x, typename Container::iterator i); |
| </pre></blockquote> |
| |
| <p> |
| Now there is only one free template parameter. And the second argument to |
| <tt>inserter</tt> must be implicitly convertible to the container's iterator, |
| else the call will not be a viable overload (allowing other functions in the |
| overload set to take precedence). Furthermore, the first parameter must have a |
| nested type named <tt>iterator</tt>, or again the binding to <tt>std::inserter</tt> |
| is not viable. Contrast this with the current situation |
| where any type can bind to <tt>Container</tt> or <tt>Iterator</tt> and those |
| types need not be anything closely related to containers or iterators. |
| </p> |
| |
| <p> |
| This can adversely impact well written code. Consider: |
| </p> |
| |
| <blockquote><pre>#include <iterator> |
| #include <string> |
| |
| namespace my |
| { |
| |
| template <class String> |
| struct my_type {}; |
| |
| struct my_container |
| { |
| template <class String> |
| void push_back(const my_type<String>&); |
| }; |
| |
| template <class String> |
| void inserter(const my_type<String>& m, my_container& c) {c.push_back(m);} |
| |
| } // my |
| |
| int main() |
| { |
| my::my_container c; |
| my::my_type<std::string> m; |
| inserter(m, c); |
| } |
| </pre></blockquote> |
| |
| <p> |
| Today this code fails because the call to <tt>inserter</tt> binds to |
| <tt>std::inserter</tt> instead of to <tt>my::inserter</tt>. However with the |
| proposed change <tt>std::inserter</tt> will no longer be a viable function which |
| leaves only <tt>my::inserter</tt> in the overload resolution set. Everything |
| works as the client intends. |
| </p> |
| |
| <p> |
| To make matters a little more insidious, the above example works today if you |
| simply change the first argument to an rvalue: |
| </p> |
| |
| <blockquote><pre> inserter(my::my_type(), c); |
| </pre></blockquote> |
| |
| <p> |
| It will also work if instantiated with some string type other than |
| <tt>std::string</tt> (or any other <tt>std</tt> type). It will also work if |
| <tt><iterator></tt> happens to not get included. |
| </p> |
| |
| <p> |
| And it will fail again for such inocuous reaons as <tt>my_type</tt> or |
| <tt>my_container</tt> privately deriving from any <tt>std</tt> type. |
| </p> |
| |
| <p> |
| It seems unfortunate that such simple changes in the client's code can result |
| in such radically differing behavior. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 24.2: |
| </p> |
| |
| <blockquote> |
| <b>24.2 Header</b> <tt><iterator></tt> <b>synopsis</b> |
| <blockquote><pre>... |
| template <class Container<del>, class Iterator</del>> |
| insert_iterator<Container> inserter(Container& x, <del>Iterator</del> <ins>typename Container::iterator</ins> i); |
| ... |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| Change 24.4.2.5: |
| </p> |
| |
| <blockquote> |
| <b>24.4.2.5 Class template</b> <tt>insert_iterator</tt> |
| <blockquote><pre>... |
| template <class Container<del>, class Iterator</del>> |
| insert_iterator<Container> inserter(Container& x, <del>Iterator</del> <ins>typename Container::iterator</ins> i); |
| ... |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| Change 24.4.2.6.5: |
| </p> |
| |
| <blockquote> |
| <p> |
| <b>24.4.2.6.5</b> <tt>inserter</tt> |
| </p> |
| <pre>template <class Container<del>, class Inserter</del>> |
| insert_iterator<Container> inserter(Container& x, <del>Inserter</del> <ins>typename Container::iterator</ins> i); |
| </pre> |
| <blockquote> |
| -1- <i>Returns:</i> <tt>insert_iterator<Container>(x,<del>typename Container::iterator(</del>i<del>)</del>)</tt>. |
| </blockquote> |
| </blockquote> |
| |
| <hr> |
| <a name="562"><h3>562. stringbuf ctor inefficient</h3></a><p><b>Section:</b> 27.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.string.streams"> [lib.string.streams]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 23 Feb 2006</p> |
| <p> |
| |
| For better efficiency, the requirement on the stringbuf ctor that |
| takes a string argument should be loosened up to let it set |
| <code>epptr()</code> beyond just one past the last initialized |
| character just like <code>overflow()</code> has been changed to be |
| allowed to do (see issue 432). That way the first call to |
| <code>sputc()</code> on an object won't necessarily cause a call to |
| <code>overflow</code>. The corresponding change should be made to the |
| string overload of the <code>str()</code> member function. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Change 27.7.1.1, p3 of the Working Draft, N1804, as follows: |
| |
| </p> |
| |
| <blockquote> |
| <pre>explicit basic_stringbuf(const basic_string<charT,traits,Allocator>& <i>s<del>tr</del></i>, |
| ios_base::openmode <i>which</i> = ios_base::in | ios_base::out); |
| </pre> |
| |
| <p> |
| -3- <i>Effects:</i> Constructs an object of class <tt>basic_stringbuf</tt>, |
| initializing the base class with <tt>basic_streambuf()</tt> |
| (27.5.2.1), and initializing <tt><i>mode</i></tt> with <tt><i>which</i></tt>. |
| Then <ins>calls <tt>str(<i>s</i>)</tt>.</ins> <del>copies the content of |
| <i>str</i> into the <tt>basic_stringbuf</tt> underlying character |
| sequence. If <tt><i>which</i> & ios_base::out</tt> is true, initializes the |
| output sequence such that <tt>pbase()</tt> points to the first underlying |
| character, <tt>epptr()</tt> points one past the last underlying character, and |
| <tt>pptr()</tt> is equal to <tt>epptr()</tt> if <tt><i>which</i> & ios_base::ate</tt> |
| is true, otherwise <tt>pptr()</tt> is equal to <tt>pbase()</tt>. If |
| <tt>which & ios_base::in</tt> is true, initializes the input sequence such |
| that <tt>eback()</tt> and <tt>gptr()</tt> point to the first underlying |
| character and <tt>egptr()</tt> points one past the last underlying character.</del> |
| </p> |
| </blockquote> |
| |
| <p> |
| |
| Change the Effects clause of the <code>str()</code> in 27.7.1.2, p2 to |
| read: |
| |
| </p> |
| <blockquote> |
| <p> |
| -2- <i>Effects:</i> Copies the content<ins>s</ins> of <tt><i>s</i></tt> into the |
| <tt>basic_stringbuf</tt> underlying character sequence <ins>and |
| initializes the input and output sequences according to <tt><i>mode</i></tt></ins>. |
| <del>If |
| <tt><i>mode</i> & ios_base::out</tt> is true, initializes the output |
| sequence such that <tt>pbase()</tt> points to the first underlying character, |
| <tt>epptr()</tt> points one past the last underlying character, and <tt>pptr()</tt> |
| is equal to <tt>epptr()</tt> if <tt><i>mode</i> & ios_base::in</tt> |
| is true, otherwise <tt>pptr()</tt> is equal to <tt>pbase()</tt>. If |
| <tt>mode & ios_base::in</tt> is true, initializes the input sequence |
| such that <tt>eback()</tt> and <tt>gptr()</tt> point to the first underlying |
| character and <tt>egptr()</tt> points one past the last underlying character.</del> |
| </p> |
| |
| <p> |
| |
| <ins>-3- <i>Postconditions:</i> If <code>mode & ios_base::out</code> is true, |
| <code>pbase()</code> points to the first underlying character and |
| <code>(epptr() >= pbase() + s.size())</code> holds; in addition, if |
| <code>mode & ios_base::in</code> is true, <code>(pptr() == pbase() |
| + s.data())</code> holds, otherwise <code>(pptr() == pbase())</code> |
| is true. If <code>mode & ios_base::in</code> is true, |
| <code>eback()</code> points to the first underlying character, and |
| <code>(gptr() == eback())</code> and <code>(egptr() == eback() + |
| s.size())</code> hold.</ins> |
| |
| </p> |
| </blockquote> |
| <hr> |
| <a name="563"><h3>563. stringbuf seeking from end</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#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 23 Feb 2006</p> |
| <p> |
| According to Table 92 (unchanged by issue 432), when <code>(way == |
| end)</code> the <code>newoff</code> value in out mode is computed as |
| the difference between <code>epptr()</code> and <code>pbase()</code>. |
| </p> |
| <p> |
| |
| This value isn't meaningful unless the value of <code>epptr()</code> |
| can be precisely controlled by a program. That used to be possible |
| until we accepted the resolution of issue 432, but since then the |
| requirements on <code>overflow()</code> have been relaxed to allow it |
| to make more than 1 write position available (i.e., by setting |
| <code>epptr()</code> to some unspecified value past |
| <code>pptr()</code>). So after the first call to |
| <code>overflow()</code> positioning the output sequence relative to |
| end will have unspecified results. |
| |
| </p> |
| <p> |
| |
| In addition, in <code>in|out</code> mode, since <code>(egptr() == |
| epptr())</code> need not hold, there are two different possible values |
| for <code>newoff</code>: <code>epptr() - pbase()</code> and |
| <code>egptr() - eback()</code>. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Change the <code>newoff</code> column in the last row of Table 94 to |
| read: |
| |
| </p> |
| <blockquote> |
| |
| the <del>end</del> <ins>high mark</ins> pointer minus the beginning |
| pointer (<code><del>xend</del> <ins>high_mark</ins> - xbeg</code>). |
| |
| </blockquote> |
| <hr> |
| <a name="564"><h3>564. stringbuf seekpos underspecified</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#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 23 Feb 2006</p> |
| <p> |
| The effects of the <code>seekpos()</code> member function of |
| <code>basic_stringbuf</code> simply say that the function positions |
| the input and/or output sequences but fail to spell out exactly |
| how. This is in contrast to the detail in which <code>seekoff()</code> |
| is described. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Change 27.7.1.3, p13 to read: |
| |
| </p> |
| <blockquote> |
| <p> |
| -13- <i>Effects:</i> <ins>Same as <tt>seekoff(off_type(<i>sp</i>), ios_base::beg, |
| <i>which</i>)</tt>.</ins> <del>Alters the stream position within the controlled sequences, |
| if possible, to correspond to the stream position stored in <tt><i>sp</i></tt> |
| (as described below).</del> |
| </p> |
| <ul> |
| <li><del>If <tt>(<i>which</i> & ios_base::in) != 0</tt>, positions the input sequence.</del></li> |
| <li><del>If <tt>(<i>which</i> & ios_base::out) != 0</tt>, positions the output sequence.</del></li> |
| <li><del>If <tt><i>sp</i></tt> is an invalid stream position, or if the function |
| positions neither sequence, the positioning operation fails. If <tt><i>sp</i></tt> |
| has not been obtained by a previous successful call to one of the positioning |
| functions (<tt>seekoff</tt>, <tt>seekpos</tt>, <tt>tellg</tt>, <tt>tellp</tt>) |
| the effect is undefined.</del></li> |
| </ul> |
| </blockquote> |
| <hr> |
| <a name="565"><h3>565. xsputn inefficient</h3></a><p><b>Section:</b> 27.5.2.4.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.put"> [lib.streambuf.virt.put]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 23 Feb 2006</p> |
| <p> |
| |
| <tt>streambuf::xsputn()</tt> is specified to have the effect of |
| "writing up to <tt>n</tt> characters to the output sequence as if by |
| repeated calls to <tt>sputc(c)</tt>." |
| |
| </p> |
| <p> |
| |
| Since <tt>sputc()</tt> is required to call <tt>overflow()</tt> when |
| <tt>(pptr() == epptr())</tt> is true, strictly speaking |
| <tt>xsputn()</tt> should do the same. However, doing so would be |
| suboptimal in some interesting cases, such as in unbuffered mode or |
| when the buffer is <tt>basic_stringbuf</tt>. |
| |
| </p> |
| <p> |
| |
| Assuming calling <tt>overflow()</tt> is not really intended to be |
| required and the wording is simply meant to describe the general |
| effect of appending to the end of the sequence it would be worthwhile |
| to mention in <tt>xsputn()</tt> that the function is not actually |
| required to cause a call to <tt>overflow()</tt>. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Add the following sentence to the <tt>xsputn()</tt> Effects clause in |
| 27.5.2.4.5, p1 (N1804): |
| |
| </p> |
| <blockquote> |
| <p> |
| -1- <i>Effects:</i> Writes up to <tt><i>n</i></tt> characters to the output |
| sequence as if by repeated calls to <tt>sputc(<i>c</i>)</tt>. The characters |
| written are obtained from successive elements of the array whose first element |
| is designated by <tt><i>s</i></tt>. Writing stops when either <tt><i>n</i></tt> |
| characters have been written or a call to <tt>sputc(<i>c</i>)</tt> would return |
| <tt>traits::eof()</tt>. <ins>It is uspecified whether the function calls |
| <tt>overflow()</tt> when <tt>(pptr() == epptr())</tt> becomes true or whether |
| it achieves the same effects by other means.</ins> |
| </p> |
| </blockquote> |
| <p> |
| |
| In addition, I suggest to add a footnote to this function with the |
| same text as Footnote 292 to make it extra clear that derived classes |
| are permitted to override <tt>xsputn()</tt> for efficiency. |
| |
| </p> |
| <hr> |
| <a name="566"><h3>566. array forms of unformatted input function undefined for zero-element arrays</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#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 23 Feb 2006</p> |
| <p> |
| |
| The array forms of unformatted input functions don't have well-defined |
| semantics for zero-element arrays in a couple of cases. The affected |
| ones (<tt>istream::get()</tt> and <tt>getline()</tt>) are supposed to |
| terminate when <tt>(n - 1)</tt> characters are stored, which obviously |
| can never be true when <tt>(n == 0)</tt> to start with. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose the following changes (references are relative to the |
| Working Draft (document N1804). |
| |
| </p> |
| <p> |
| |
| Change 27.6.1.3, p8 (<tt>istream::get()</tt>), bullet 1 as follows: |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| <ins>if <tt>(n < 1)</tt> is true or </ins> <tt>(n - 1)</tt> |
| characters are stored; |
| |
| </p> |
| </blockquote> |
| <p> |
| |
| Similarly, change 27.6.1.3, p18 (<tt>istream::getline()</tt>), bullet |
| 3 as follows: |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| <ins><tt>(n < 1)</tt> is true or </ins><tt>(n - 1)</tt> characters |
| are stored (in which case the function calls |
| <tt>setstate(failbit)</tt>). |
| |
| </p> |
| </blockquote> |
| <p> |
| |
| Finally, change p21 as follows: |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| In any case, <ins>provided <tt>(n > 0)</tt> is true, </ins>it then |
| stores a null character (using charT()) into the next successive |
| location of the array. |
| |
| </p> |
| </blockquote> |
| <hr> |
| <a name="567"><h3>567. streambuf inserter and extractor should be unformatted</h3></a><p><b>Section:</b> 27.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.format"> [lib.iostream.format]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 25 Feb 2006</p> |
| <p> |
| |
| Issue 60 explicitly made the extractor and inserter operators that |
| take a <tt>basic_streambuf*</tt> argument formatted input and output |
| functions, respectively. I believe that's wrong, certainly in the |
| case of the extractor, since formatted functions begin by extracting |
| and discarding whitespace. The extractor should not discard any |
| characters. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose to change each operator to behave as unformatted input and |
| output function, respectively. The changes below are relative to the |
| working draft document number N1804. |
| |
| </p> |
| <p> |
| |
| Specifically, change 27.6.1.2.3, p14 as follows: |
| |
| </p> |
| |
| <p> |
| </p><blockquote> |
| |
| <i>Effects</i>: Behaves as a<ins>n un</ins>formatted input function |
| (as described in <del>27.6.1.2.1</del><ins>27.6.1.3, paragraph |
| 1</ins>). |
| |
| </blockquote> |
| <p></p> |
| <p> |
| |
| And change 27.6.2.5.3, p7 as follows: |
| |
| </p> |
| |
| <p> |
| </p><blockquote> |
| |
| <i>Effects</i>: Behaves as a<ins>n un</ins>formatted output function |
| (as described in <del>27.6.2.5.1</del><ins>27.6.2.6, paragraph |
| 1</ins>). |
| |
| </blockquote> |
| <p></p> |
| <hr> |
| <a name="568"><h3>568. log2 overloads missing</h3></a><p><b>Section:</b> TR1 8.16.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.c99.cmath.over"> [tr.c99.cmath.over]</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> 7 Mar 2006</p> |
| <p> |
| <tt>log2</tt> is missing from the list of "additional overloads" in 8.16.4p1. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add <tt>log2</tt> to the list of functions in 8.16.4p1. |
| </p> |
| <hr> |
| <a name="570"><h3>570. Request adding additional explicit specializations of char_traits</h3></a><p><b>Section:</b> 21.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits"> [lib.char.traits]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Jack Reeves <b>Date:</b> 6 Apr 2006</p> |
| <p> |
| Currently, the Standard Library specifies only a declaration for template class |
| char_traits<> and requires the implementation provide two explicit |
| specializations: char_traits<char> and char_traits<wchar_t>. I feel the Standard |
| should require explicit specializations for all built-in character types, i.e. |
| char, wchar_t, unsigned char, and signed char. |
| </p> |
| <p> |
| I have put together a paper (N1985) that describes this in more detail and |
| includes all the necessary wording. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="571"><h3>571. Update C90 references to C99?</h3></a><p><b>Section:</b> 1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/intro.html#intro.refs"> [intro.refs]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 8 Apr 2006</p> |
| <p> |
| 1.2 Normative references [intro.refs] of the WP currently refers to ISO/IEC |
| 9899:1990, Programming languages - C. Should that be changed to ISO/IEC |
| 9899:1999? |
| </p> |
| <p> |
| What impact does this have on the library? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 1.2/1 [intro.refs] of the WP, change: |
| </p> |
| <blockquote> |
| <ul> |
| <li>ISO/IEC 9899:<del>1990</del><ins>1999 + TC1 + TC2</ins>, <i>Programming languages - C</i> |
| </li> |
| </ul> |
| </blockquote> |
| |
| <hr> |
| <a name="572"><h3>572. Oops, we gave 507 WP status</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#New">New</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 11 Apr 2006</p> |
| <p> |
| In Berlin, as a working group, we voted in favor of N1932 which makes issue 507 moot: |
| variate_generator has been eliminated. Then in full committee we voted to give |
| this issue WP status (mistakenly). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Strike the proposed resolution of issue 507. |
| </p> |
| <p><i>[ |
| post-Portland: Howard recommends NAD. The proposed resolution of 507 no longer |
| exists in the current WD. |
| ]</i></p> |
| <hr> |
| <a name="573"><h3>573. C++0x file positioning should handle modern file sizes</h3></a><p><b>Section:</b> 27.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fpos"> [lib.fpos]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 12 Apr 2006</p> |
| <p> |
| There are two deficiencies related to file sizes: |
| </p> |
| <ol> |
| <li>It doesn't appear that the Standard Library is specified in |
| a way that handles modern file sizes, which are often too |
| large to be represented by an unsigned long.</li> |
| |
| <li>The std::fpos class does not currently have the ability to |
| set/get file positions.</li> |
| </ol> |
| <p> |
| The Dinkumware implementation of the Standard Library as shipped with the Microsoft compiler copes with these issues by: |
| </p> |
| <ol type="A"> |
| <li>Defining fpos_t be long long, which is large enough to |
| represent any file position likely in the foreseeable future.</li> |
| |
| <li>Adding member functions to class fpos. For example, |
| <blockquote><pre>fpos_t seekpos() const; |
| </pre></blockquote> |
| </li> |
| </ol> |
| <p> |
| Because there are so many types relating to file positions and offsets (fpos_t, |
| fpos, pos_type, off_type, streamoff, streamsize, streampos, wstreampos, and |
| perhaps more), it is difficult to know if the Dinkumware extensions are |
| sufficient. But they seem a useful starting place for discussions, and they do |
| represent existing practice. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="574"><h3>574. DR 369 Contradicts Text</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#New">New</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 18 Apr 2006</p> |
| <p> |
| lib.iostream.objects requires that the standard stream objects are never |
| destroyed, and it requires that they be destroyed. |
| </p> |
| <p> |
| DR 369 adds words to say that we really mean for ios_base::Init objects to force |
| construction of standard stream objects. It ends, though, with the phrase "these |
| stream objects shall be destroyed after the destruction of dynamically ...". |
| However, the rule for destruction is stated in the standard: "The objects are |
| not destroyed during program execution." |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="575"><h3>575. the specification of ~shared_ptr is MT-unfriendly, makes implementation assumptions</h3></a><p><b>Section:</b> 20.6.6.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.util.smartptr.shared.dest"> [lib.util.smartptr.shared.dest]</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> 23 Apr 2006</p> |
| <p> |
| [tr.util.smartptr.shared.dest] says in its second bullet: |
| </p> |
| |
| <p> |
| "If *this shares ownership with another shared_ptr instance (use_count() > 1), |
| decrements that instance's use count." |
| </p> |
| |
| <p> |
| The problem with this formulation is that it presupposes the existence of an |
| "use count" variable that can be decremented and that is part of the state of a |
| shared_ptr instance (because of the "that instance's use count".) |
| </p> |
| |
| <p> |
| This is contrary to the spirit of the rest of the specification that carefully |
| avoids to require an use count variable. Instead, use_count() is specified to |
| return a value, a number of instances. |
| </p> |
| |
| <p> |
| In multithreaded code, the usual implicit assumption is that a shared variable |
| should not be accessed by more than one thread without explicit synchronization, |
| and by introducing the concept of an "use count" variable, the current wording |
| implies that two shared_ptr instances that share ownership cannot be destroyed |
| simultaneously. |
| </p> |
| |
| <p> |
| In addition, if we allow the interpretation that an use count variable is part |
| of shared_ptr's state, this would lead to other undesirable consequences WRT |
| multiple threads. For example, |
| </p> |
| |
| <blockquote><pre>p1 = p2; |
| </pre></blockquote> |
| |
| <p> |
| would now visibly modify the state of p2, a "write" operation, requiring a lock. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the first two bullets of [lib.util.smartptr.shared.dest]/1 to: |
| </p> |
| |
| <blockquote><p> |
| </p><ul> |
| <li>If <tt>*this</tt> is <i>empty</i> <ins>or shares ownership with another |
| <tt>shared_ptr</tt> instance (<tt>use_count() > 1</tt>)</ins>, there are no side effects.</li> |
| <li><del>If <tt>*this</tt> <i>shares ownership</i> with another <tt>shared_ptr</tt> instance |
| (<tt>use_count() > 1</tt>), decrements that instance's use count.</del></li> |
| </ul> |
| <p></p></blockquote> |
| |
| <p> |
| Add the following paragraph after [lib.util.smartptr.shared.dest]/1: |
| </p> |
| |
| <blockquote><p> |
| [<i>Note:</i> since the destruction of <tt>*this</tt> decreases the number of instances in |
| <tt>*this</tt>'s ownership group by one, all <tt>shared_ptr</tt> instances that share ownership |
| with <tt>*this</tt> will report an <tt>use_count()</tt> that is one lower than its previous value |
| after <tt>*this</tt> is destroyed. <i>--end note</i>] |
| </p></blockquote> |
| <hr> |
| <a name="576"><h3>576. find_first_of is overconstrained</h3></a><p><b>Section:</b> 25.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.find.first.of"> [lib.alg.find.first.of]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Doug Gregor <b>Date:</b> 25 Apr 2006</p> |
| <p> |
| In 25.1.4 Find First [lib.alg.find.first], the two iterator type parameters to |
| find_first_of are specified to require Forward Iterators, as follows: |
| </p> |
| |
| <blockquote><pre>template<class ForwardIterator1, class ForwardIterator2> |
| ForwardIterator1 |
| find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, |
| ForwardIterator2 first2, ForwardIterator2 last2); |
| template<class ForwardIterator1, class ForwardIterator2, |
| class BinaryPredicate> |
| ForwardIterator1 |
| find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, |
| ForwardIterator2 first2, ForwardIterator2 last2, |
| BinaryPredicate pred); |
| </pre></blockquote> |
| |
| <p> |
| However, ForwardIterator1 need not actually be a Forward Iterator; an Input |
| Iterator suffices, because we do not need the multi-pass property of the Forward |
| Iterator or a true reference. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the declarations of <tt>find_first_of</tt> to: |
| </p> |
| |
| <blockquote><pre>template<class <del>ForwardIterator1</del><ins>InputIterator1</ins>, class ForwardIterator2> |
| <del>ForwardIterator1</del><ins>InputIterator1</ins> |
| find_first_of(<del>ForwardIterator1</del><ins>InputIterator1</ins> first1, <del>ForwardIterator1</del><ins>InputIterator1</ins> last1, |
| ForwardIterator2 first2, ForwardIterator2 last2); |
| template<class <del>ForwardIterator1</del><ins>InputIterator1</ins>, class ForwardIterator2, |
| class BinaryPredicate> |
| <del>ForwardIterator1</del><ins>InputIterator1</ins> |
| find_first_of(<del>ForwardIterator1</del><ins>InputIterator1</ins> first1, <del>ForwardIterator1</del><ins>InputIterator1</ins> last1, |
| ForwardIterator2 first2, ForwardIterator2 last2, |
| BinaryPredicate pred); |
| </pre></blockquote> |
| |
| <hr> |
| <a name="577"><h3>577. upper_bound(first, last, ...) cannot return last</h3></a><p><b>Section:</b> 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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Seungbeom Kim <b>Date:</b> 3 May 2006</p> |
| <p> |
| ISO/IEC 14882:2003 says: |
| </p> |
| |
| <blockquote> |
| <p> |
| 25.3.3.2 upper_bound |
| </p> |
| <p> |
| <i>Returns:</i> The furthermost iterator <tt>i</tt> in the range |
| <tt>[<i>first</i>, <i>last</i>)</tt> such that |
| for any iterator <tt>j</tt> in the range <tt>[<i>first</i>, i)</tt> the following corresponding |
| conditions hold: <tt>!(value < *j)</tt> or <tt><i>comp</i>(<i>value</i>, *j) == false</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| From the description above, upper_bound cannot return last, since it's |
| not in the interval [first, last). This seems to be a typo, because if |
| value is greater than or equal to any other values in the range, or if |
| the range is empty, returning last seems to be the intended behaviour. |
| The corresponding interval for lower_bound is also [first, last]. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change [lib.upper.bound]: |
| </p> |
| |
| <blockquote> |
| <p> |
| <i>Returns:</i> The furthermost iterator <tt>i</tt> in the range |
| <tt>[<i>first</i>, <i>last</i><del>)</del><ins>]</ins></tt> such that |
| for any iterator <tt>j</tt> in the range <tt>[<i>first</i>, i)</tt> the following corresponding |
| conditions hold: <tt>!(value < *j)</tt> or <tt><i>comp</i>(<i>value</i>, *j) == false</tt>. |
| </p> |
| </blockquote> |
| |
| <hr> |
| <a name="578"><h3>578. purpose of hint to allocator::allocate()</h3></a><p><b>Section:</b> 20.6.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.allocator.members"> [lib.allocator.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 17 May 2006</p> |
| <p> |
| |
| The description of the allocator member function |
| <code>allocate()</code> requires that the <i>hint</i> argument be |
| either 0 or a value previously returned from <code>allocate()</code>. |
| Footnote 227 further suggests that containers may pass the address of |
| an adjacent element as this argument. |
| |
| </p> |
| <p> |
| |
| I believe that either the footnote is wrong or the normative |
| requirement that the argument be a value previously returned from a |
| call to <code>allocate()</code> is wrong. The latter is supported by |
| the resolution to issue 20-004 proposed in c++std-lib-3736 by Nathan |
| Myers. In addition, the <i>hint</i> is an ordinary void* and not the |
| <code>pointer</code> type returned by <code>allocate()</code>, with |
| the two types potentially being incompatible and the requirement |
| impossible to satisfy. |
| |
| </p> |
| <p> |
| |
| See also c++std-lib-14323 for some more context on where this came up |
| (again). |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Remove the requirement in 20.6.1.1, p4 that the hint be a value |
| previously returned from <code>allocate()</code>. Specifically, change |
| the paragraph as follows: |
| |
| </p> |
| <p> |
| |
| <i>Requires</i>: <i>hint</i> <ins>is </ins>either 0 or <del>previously |
| obtained from member <code>allocate</code> and not yet passed to |
| member <code>deallocate</code></del><ins> the address of a byte in |
| memory (1.7)</ins>. |
| |
| </p> |
| <hr> |
| <a name="579"><h3>579. erase(iterator) for unordered containers should not return an iterator</h3></a><p><b>Section:</b> 23.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.unord.req"> [lib.unord.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> JoaquÃn M López Muñoz <b>Date:</b> 13 Jun 2006</p> |
| <p> |
| See |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2023.pdf">N2023</a> |
| for full discussion. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Option 1: |
| </p> |
| |
| <p> |
| The problem can be eliminated by omitting the requirement that <tt>a.erase(q)</tt> return an |
| iterator. This is, however, in contrast with the equivalent requirements for other |
| standard containers. |
| </p> |
| |
| <p> |
| Option 2: |
| </p> |
| |
| <p> |
| <tt>a.erase(q)</tt> can be made to compute the next iterator only when explicitly requested: |
| the technique consists in returning a proxy object implicitly convertible to <tt>iterator</tt>, so |
| that |
| </p> |
| |
| <blockquote><pre>iterator q1=a.erase(q); |
| </pre></blockquote> |
| |
| <p> |
| works as expected, while |
| </p> |
| |
| <blockquote><pre>a.erase(q); |
| </pre></blockquote> |
| |
| <p> |
| does not ever invoke the conversion-to-iterator operator, thus avoiding the associated |
| computation. To allow this technique, some sections of TR1 along the line "return value |
| is an iterator..." should be changed to "return value is an unspecified object implicitly |
| convertible to an iterator..." Although this trick is expected to work transparently, it can |
| have some collateral effects when the expression <tt>a.erase(q)</tt> is used inside generic |
| code. |
| </p> |
| |
| <hr> |
| <a name="580"><h3>580. unused allocator members</h3></a><p><b>Section:</b> 20.1.6 <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#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 14 June 2006</p> |
| <p> |
| |
| C++ Standard Library templates that take an allocator as an argument |
| are required to call the <code>allocate()</code> and |
| <code>deallocate()</code> members of the allocator object to obtain |
| storage. However, they do not appear to be required to call any other |
| allocator members such as <code>construct()</code>, |
| <code>destroy()</code>, <code>address()</code>, and |
| <code>max_size()</code>. This makes these allocator members less than |
| useful in portable programs. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| It's unclear to me whether the absence of the requirement to use these |
| allocator members is an unintentional omission or a deliberate |
| choice. However, since the functions exist in the standard allocator |
| and since they are required to be provided by any user-defined |
| allocator I believe the standard ought to be clarified to explictly |
| specify whether programs should or should not be able to rely on |
| standard containers calling the functions. |
| |
| </p> |
| <p> |
| |
| I propose that all containers be required to make use of these |
| functions. |
| |
| </p> |
| <hr> |
| <a name="581"><h3>581. <code>flush()</code> not unformatted function</h3></a><p><b>Section:</b> 27.6.2.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.unformatted"> [lib.ostream.unformatted]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 14 June 2006</p> |
| <p> |
| |
| The resolution of issue 60 changed <code>basic_ostream::flush()</code> |
| so as not to require it to behave as an unformatted output function. |
| That has at least two in my opinion problematic consequences: |
| |
| </p> |
| <p> |
| |
| First, <code>flush()</code> now calls <code>rdbuf()->pubsync()</code> |
| unconditionally, without regard to the state of the stream. I can't |
| think of any reason why <code>flush()</code> should behave differently |
| from the vast majority of stream functions in this respect. |
| |
| </p> |
| <p> |
| |
| Second, <code>flush()</code> is not required to catch exceptions from |
| <code>pubsync()</code> or set <code>badbit</code> in response to such |
| events. That doesn't seem right either, as most other stream functions |
| do so. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose to revert the resolution of issue 60 with respect to |
| <code>flush()</code>. Specifically, I propose to change 27.6.2.6, p7 |
| as follows: |
| |
| </p> |
| |
| Effects: <ins>Behaves as an unformatted output function (as described |
| in 27.6.2.6, paragraph 1). </ins>If <code>rdbuf()</code> is not a null |
| pointer, <ins>constructs a sentry object. If this object returns |
| <code>true</code> when converted to a value of type bool the function |
| </ins>calls <code>rdbuf()->pubsync()</code>. If that function returns |
| -1 calls <code>setstate(badbit)</code> (which may throw |
| <code>ios_base::failure</code> (27.4.4.3)). <ins>Otherwise, if the |
| sentry object returns <code>false</code>, does nothing.</ins><del>Does |
| not behave as an unformatted output function (as described in |
| 27.6.2.6, paragraph 1).</del> |
| |
| <hr> |
| <a name="582"><h3>582. specialized algorithms and volatile storage</h3></a><p><b>Section:</b> 20.6.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.uninitialized.copy"> [lib.uninitialized.copy]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 14 June 2006</p> |
| <p> |
| |
| The specialized algorithms [lib.specialized.algorithms] are specified |
| as having the general effect of invoking the following expression: |
| |
| </p> |
| <p> |
| </p><pre> |
| new (static_cast<void*>(&*i)) |
| typename iterator_traits<ForwardIterator>::value_type (x) |
| |
| </pre> |
| <p></p> |
| <p> |
| |
| This expression is ill-formed when the type of the subexpression |
| <code>&*i</code> is some volatile-qualified <code>T</code>. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| In order to allow these algorithms to operate on volatile storage I |
| propose to change the expression so as to make it well-formed even for |
| pointers to volatile types. Specifically, I propose the following |
| changes to clauses 20 and 24. Change 20.6.4.1, p1 to read: |
| |
| </p> |
| <p> |
| </p><pre> |
| <i>Effects</i>: |
| |
| typedef typename iterator_traits<ForwardIterator>::pointer pointer; |
| typedef typename iterator_traits<ForwardIterator>::value_type value_type; |
| |
| for (; first != last; ++result, ++first) |
| new (static_cast<void*>(const_cast<pointer>(&*result)) |
| value_type (*first); |
| |
| </pre> |
| <p></p> |
| <p> |
| |
| change 20.6.4.2, p1 to read |
| |
| </p> |
| <p> |
| </p><pre> |
| <i>Effects</i>: |
| |
| typedef typename iterator_traits<ForwardIterator>::pointer pointer; |
| typedef typename iterator_traits<ForwardIterator>::value_type value_type; |
| |
| for (; first != last; ++result, ++first) |
| new (static_cast<void*>(const_cast<pointer>(&*first)) |
| value_type (*x); |
| |
| </pre> |
| <p></p> |
| <p> |
| |
| and change 20.6.4.3, p1 to read |
| |
| </p> |
| <p> |
| </p><pre> |
| <i>Effects</i>: |
| |
| typedef typename iterator_traits<ForwardIterator>::pointer pointer; |
| typedef typename iterator_traits<ForwardIterator>::value_type value_type; |
| |
| for (; n--; ++first) |
| new (static_cast<void*>(const_cast<pointer>(&*first)) |
| value_type (*x); |
| |
| </pre> |
| <p></p> |
| <p> |
| |
| In addition, since there is no partial specialization for |
| <code>iterator_traits<volatile T*></code> I propose to add one |
| to parallel such specialization for <const T*>. Specifically, I |
| propose to add the following text to the end of 24.3.1, p3: |
| |
| </p> |
| <p> |
| |
| and for pointers to volatile as |
| |
| </p> |
| <p> |
| </p><pre> |
| namespace std { |
| template<class T> struct iterator_traits<volatile T*> { |
| typedef ptrdiff_t difference_type; |
| typedef T value_type; |
| typedef volatile T* pointer; |
| typedef volatile T& reference; |
| typedef random_access_iterator_tag iterator_category; |
| }; |
| } |
| |
| </pre> |
| <p></p> |
| <p> |
| |
| Note that the change to <code>iterator_traits</code> isn't necessary |
| in order to implement the specialized algorithms in a way that allows |
| them to operate on volatile strorage. It is only necesassary in order |
| to specify their effects in terms of <code>iterator_traits</code> as |
| is done here. Implementations can (and some do) achieve the same |
| effect by means of function template overloading. |
| |
| </p> |
| <hr> |
| <a name="583"><h3>583. div() for unsigned integral types</h3></a><p><b>Section:</b> 26.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.c.math"> [lib.c.math]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 15 Jun 2006</p> |
| <p> |
| There is no div() function for unsigned integer types. |
| </p> |
| <p> |
| There are several possible resolutions. The simplest one is noted below. Other |
| possibilities include a templated solution. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to 26.7 [lib.c.math] paragraph 8: |
| </p> |
| |
| <blockquote><pre>struct udiv_t div(unsigned, unsigned); |
| struct uldiv_t div(unsigned long, unsigned long); |
| struct ulldiv_t div(unsigned long long, unsigned long long); |
| </pre></blockquote> |
| |
| <hr> |
| <a name="584"><h3>584. missing int pow(int,int) functionality</h3></a><p><b>Section:</b> 26.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.c.math"> [lib.c.math]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 15 Jun 2006</p> |
| <p> |
| There is no pow() function for any integral type. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add something like: |
| </p> |
| |
| <blockquote><pre>template< typename T> |
| T power( T x, int n ); |
| // requires: n >=0 |
| </pre></blockquote> |
| <hr> |
| <a name="585"><h3>585. facet error reporting</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> Martin Sebor, Paolo Carlini <b>Date:</b> 22 June 2006</p> |
| <p> |
| |
| Section 22.2, paragraph 2 requires facet <code>get()</code> members |
| that take an <code>ios_base::iostate&</code> argument, |
| <code><i>err</i></code>, to ignore the (initial) value of the |
| argument, but to set it to <code>ios_base::failbit</code> in case of a |
| parse error. |
| |
| </p> |
| <p> |
| |
| We believe there are a few minor problems with this blanket |
| requirement in conjunction with the wording specific to each |
| <code>get()</code> member function. |
| |
| </p> |
| <p> |
| |
| First, besides <code>get()</code> there are other member functions |
| with a slightly different name (for example, |
| <code>get_date()</code>). It's not completely clear that the intent of |
| the paragraph is to include those as well, and at least one |
| implementation has interpreted the requirement literally. |
| |
| </p> |
| <p> |
| |
| Second, the requirement to "set the argument to |
| <code>ios_base::failbit</code> suggests that the functions are not |
| permitted to set it to any other value (such as |
| <code>ios_base::eofbit</code>, or even <code>ios_base::eofbit | |
| ios_base::failbit</code>). |
| |
| </p> |
| <p> |
| |
| However, 22.2.2.1.2, p5 (Stage 3 of <code>num_get</code> parsing) and |
| p6 (<code>bool</code> parsing) specifies that the <code>do_get</code> |
| functions perform <code><i>err</i> |= ios_base::eofbit</code>, which |
| contradicts the earlier requirement to ignore <i>err</i>'s initial |
| value. |
| |
| </p> |
| <p> |
| |
| 22.2.6.1.2, p1 (the Effects clause of the <code>money_get</code> |
| facet's <code>do_get</code> member functions) also specifies that |
| <code><i>err</i></code>'s initial value be used to compute the final |
| value by ORing it with either <code>ios_base::failbit</code> or |
| with<code>ios_base::eofbit | ios_base::failbit</code>. |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| We believe the intent is for all facet member functions that take an |
| <code>ios_base::iostate&</code> argument to: |
| |
| </p> |
| <p> |
| </p><ul> |
| <li> |
| |
| ignore the initial value of the <code><i>err</i></code> argument, |
| |
| </li> |
| <li> |
| |
| reset <code><i>err</i></code> to <code>ios_base::goodbit</code> prior |
| to any further processing, |
| |
| </li> |
| <li> |
| |
| and set either <code>ios_base::eofbit</code>, or |
| <code>ios_base::failbit</code>, or both in <code><i>err</i></code>, as |
| appropriate, in response to reaching the end-of-file or on parse |
| error, or both. |
| |
| </li> |
| </ul> |
| <p></p> |
| <p> |
| |
| To that effect we propose to change 22.2, p2 as follows: |
| |
| </p> |
| <p> |
| |
| The <i>put</i><del>()</del> members make no provision for error |
| reporting. (Any failures of the OutputIterator argument must be |
| extracted from the returned iterator.) <ins>Unless otherwise |
| specified, </ins>the <i>get</i><del>()</del> members <ins>that</ins> |
| take an <code>ios_base::iostate&</code> argument <del>whose value |
| they ignore, but set to ios_base::failbit in case of a parse |
| error.</del><ins>, <code><i>err</i></code>, start by evaluating |
| <code>err = ios_base::goodbit</code>, and may subsequently set |
| <i>err</i> to either <code>ios_base::eofbit</code>, or |
| <code>ios_base::failbit</code>, or <code>ios_base::eofbit | |
| ios_base::failbit</code> in response to reaching the end-of-file or in |
| case of a parse error, or both, respectively.</ins> |
| |
| </p> |
| <hr> |
| <a name="586"><h3>586. string inserter not a formatted function</h3></a><p><b>Section:</b> 21.3.7.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.io"> [lib.string.io]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 22 June 2006</p> |
| <p> |
| |
| Section and paragraph numbers in this paper are relative to the |
| working draft document number N2009 from 4/21/2006. |
| |
| </p> |
| |
| <p> |
| |
| The <code>basic_string</code> extractor in 21.3.7.9, p1 is clearly |
| required to behave as a formatted input function, as is the |
| <code>std::getline()</code> overload for string described in p7. |
| |
| </p> |
| <p> |
| |
| However, the <code>basic_string</code> inserter described in p5 of the |
| same section has no such requirement. This has implications on how the |
| operator responds to exceptions thrown from <code>xsputn()</code> |
| (formatted output functions are required to set <code>badbit</code> |
| and swallow the exception unless <code>badbit</code> is also set in |
| <code>exceptions()</code>; the string inserter doesn't have any such |
| requirement). |
| |
| </p> |
| <p> |
| |
| I don't see anything in the spec for the string inserter that would |
| justify requiring it to treat exceptions differently from all other |
| similar operators. (If it did, I think it should be made this explicit |
| by saying that the operator "does not behave as a formatted output |
| function" as has been made customary by the adoption of the resolution |
| of issue 60). |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose to change the Effects clause in 21.3.7.9, p5, as follows: |
| |
| </p> |
| <p> |
| </p><blockquote> |
| |
| <i>Effects</i>: <del>Begins by constructing a sentry object k as if k |
| were constructed by typename <code>basic_ostream<charT, |
| traits>::sentry k (os)</code>. If <code>bool(k)</code> is |
| <code>true</code>, </del><ins>Behaves as a formatted output function |
| (27.6.2.5.1). After constructing a <code>sentry</code> object, if |
| this object returns <code>true</code> when converted to a value of |
| type <code>bool</code>, determines padding as described in |
| 22.2.2.2.2</ins>, then inserts the resulting sequence of characters |
| <code><i>seq</i></code> as if by calling <code>os.rdbuf()->sputn(seq , |
| n)</code>, where <code><i>n</i></code> is the larger of |
| <code>os.width()</code> and <code>str.size()</code>; then calls |
| <code>os.width(0)</code>. <del>If the call to sputn fails, calls |
| <code>os.setstate(ios_base::failbit)</code>.</del> |
| |
| </blockquote> |
| <p></p> |
| <p> |
| |
| This proposed resilution assumes the resolution of issue 394 (i.e., |
| that all formatted output functions are required to set |
| <code>ios_base::badbit</code> in response to any kind of streambuf |
| failure), and implicitly assumes that a return value of |
| <code>sputn(seq, <i>n</i>)</code> other than <code><i>n</i></code> |
| indicates a failure. |
| |
| </p> |
| <hr> |
| <a name="587"><h3>587. iststream ctor missing description</h3></a><p><b>Section:</b> D.7.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.istrstream.cons"> [depr.istrstream.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 22 June 2006</p> |
| <p> |
| |
| The <code>iststream(char*, streamsize)</code> ctor is in the class |
| synopsis in D.7.2 but its signature is missing in the description |
| below (in D.7.2.1). |
| |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| This seems like a simple editorial issue and the missing signature can |
| be added to the one for <code>const char*</code> in paragraph 2. |
| |
| </p> |
| <hr> |
| <a name="588"><h3>588. requirements on zero sized tr1::arrays and other details</h3></a><p><b>Section:</b> 23.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.array"> [lib.array]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Gennaro Prota <b>Date:</b> 18 Jul 2006</p> |
| <p> |
| The wording used for section 23.2.1 [lib.array] seems to be subtly |
| ambiguous about zero sized arrays (N==0). Specifically: |
| </p> |
| <p> |
| * "An instance of array<T, N> stores N elements of type T, so that |
| [...]" |
| </p> |
| <p> |
| Does this imply that a zero sized array object stores 0 elements, i.e. |
| that it cannot store any element of type T? The next point clarifies |
| the rationale behind this question, basically how to implement begin() |
| and end(): |
| </p> |
| <p> |
| * 23.2.1.5 [lib.array.zero], p2: "In the case that N == 0, begin() == |
| end() == unique value." |
| </p> |
| <p> |
| What does "unique" mean in this context? Let's consider the following |
| possible implementations, all relying on a partial specialization: |
| </p> |
| <blockquote><pre>a) |
| template< typename T > |
| class array< T, 0 > { |
| |
| .... |
| |
| iterator begin() |
| { return iterator( reinterpret_cast< T * >( this ) ); } |
| .... |
| |
| }; |
| </pre></blockquote> |
| <p> |
| This has been used in boost, probably intending that the return value |
| had to be unique to the specific array object and that array couldn't |
| store any T. Note that, besides relying on a reinterpret_cast, has |
| (more than potential) alignment problems. |
| </p> |
| <blockquote><pre>b) |
| template< typename T > |
| class array< T, 0 > { |
| |
| T t; |
| |
| iterator begin() |
| { return iterator( &t ); } |
| .... |
| |
| }; |
| </pre></blockquote> |
| <p> |
| This provides a value which is unique to the object and to the type of |
| the array, but requires storing a T. Also, it would allow the user to |
| mistakenly provide an initializer list with one element. |
| </p> |
| <p> |
| A slight variant could be returning *the* null pointer of type T |
| </p> |
| <blockquote><pre> return static_cast<T*>(0); |
| </pre></blockquote> |
| <p> |
| In this case the value would be unique to the type array<T, 0> but not |
| to the objects (all objects of type array<T, 0> with the same value |
| for T would yield the same pointer value). |
| </p> |
| <p> |
| Furthermore this is inconsistent with what the standard requires from |
| allocation functions (see library issue 9). |
| </p> |
| <p> |
| c) same as above but with t being a static data member; again, the |
| value would be unique to the type, not to the object. |
| </p> |
| <p> |
| d) to avoid storing a T *directly* while disallowing the possibility |
| to use a one-element initializer list a non-aggregate nested class |
| could be defined |
| </p> |
| <blockquote><pre> struct holder { holder() {} T t; } h; |
| </pre></blockquote> |
| <p> |
| and then begin be defined as |
| </p> |
| <blockquote><pre> iterator begin() { return &h.t; } |
| </pre></blockquote> |
| <p> |
| But then, it's arguable whether the array stores a T or not. |
| Indirectly it does. |
| </p> |
| <p> |
| ----------------------------------------------------- |
| </p> |
| <p> |
| Now, on different issues: |
| </p> |
| <p> |
| * what's the effect of calling assign(T&) on a zero-sized array? There |
| seems to be only mention of front() and back(), in 23.2.1 [lib.array] |
| p4 (I would also suggest to move that bullet to section 23.2.1.5 |
| [lib.array.zero], for locality of reference) |
| </p> |
| <p> |
| * (minor) the opening paragraph of 23.2.1 [lib.array] wording is a bit |
| inconsistent with that of other sequences: that's not a problem in |
| itself, but compare it for instance with "A vector is a kind of |
| sequence that supports random access iterators"; though the intent is |
| obvious one might argue that the wording used for arrays doesn't tell |
| what an array is, and relies on the reader to infer that it is what |
| the <array> header defines. |
| </p> |
| <p> |
| * it would be desiderable to have a static const data member of type |
| std::size_t, with value N, for usage as integral constant expression |
| </p> |
| <p> |
| * section 23.1 [lib.container.requirements] seem not to consider |
| fixed-size containers at all, as it says: "[containers] control |
| allocation and deallocation of these objects [the contained objects] |
| through constructors, destructors, *insert and erase* operations" |
| </p> |
| <p> |
| * max_size() isn't specified: the result is obvious but, technically, |
| it relies on table 80: "size() of the largest possible container" |
| which, again, doesn't seem to consider fixed size containers |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p> |
| <hr> |
| <a name="589"><h3>589. Requirements on iterators of member template functions of containers</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#New">New</a> <b>Submitter:</b> Peter Dimov <b>Date:</b> 2 Aug 2006</p> |
| <p> |
| There appears to be no requirements on the InputIterators used in sequences in 23.1.1 in |
| terms of their value_type, and the requirements in 23.1.2 appear to be overly strict |
| (requires InputIterator::value_type be the same type as the container's value_type). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 23.1.1 p3: |
| </p> |
| |
| <blockquote> |
| In Tables 82 and 83, <tt>X</tt> denotes a sequence class, <tt>a</tt> denotes a |
| value of <tt>X</tt>, <tt>i</tt> and <tt>j</tt> denote iterators satisfying input |
| iterator requirements <ins>and refer to elements <ins>implicitly |
| convertible to</ins> <tt>value_type</tt></ins>, <tt>[i, j)</tt> denotes a valid |
| range, <tt>n</tt> denotes a value of <tt>X::size_type</tt>, <tt>p</tt> denotes a |
| valid iterator to <tt>a</tt>, <tt>q</tt> denotes a valid dereferenceable |
| iterator to <tt>a</tt>, <tt>[q1, q2)</tt> denotes a valid range in <tt>a</tt>, |
| and <tt>t</tt> denotes a value of <tt>X::value_type</tt>. |
| </blockquote> |
| |
| <p> |
| Change 23.1.2 p7: |
| </p> |
| |
| <blockquote> |
| In Table 84, <tt>X</tt> is an associative container class, <tt>a</tt> is a value |
| of <tt>X</tt>, <tt>a_uniq</tt> is a value of <tt>X</tt> when <tt>X</tt> supports |
| unique keys, and <tt>a_eq</tt> is a value of <tt>X</tt> when <tt>X</tt> supports |
| multiple keys, <tt>i</tt> and <tt>j</tt> satisfy input iterator requirements and |
| refer to elements <del>of</del> <ins>implicitly convertible to</ins> |
| <tt>value_type</tt>, <tt>[i, j)</tt> is a valid range, <tt>p</tt> is a valid |
| iterator to <tt>a</tt>, <tt>q</tt> is a valid dereferenceable iterator to |
| <tt>a</tt>, <tt>[q1, q2)</tt> is a valid range in <tt>a</tt>, <tt>t</tt> is a |
| value of <tt>X::value_type</tt>, <tt>k</tt> is a value of <tt>X::key_type</tt> |
| and <tt>c</tt> is a value of type <tt>X::key_compare</tt>. |
| </blockquote> |
| |
| <hr> |
| <a name="590"></a><h3><a name="590">590. Type traits implementation latitude should be removed for C++0x</a></h3><p><b>Section:</b> <font color="red">20.4.9</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 10 Aug 2006</p> |
| <p> |
| 20.4.9 [lib.meta.req], Implementation requirements, provides latitude for type |
| traits implementers that is not needed in C++0x. It includes the wording: |
| </p> |
| |
| <blockquote> |
| [<i>Note:</i> the latitude granted to implementers in this clause is temporary, |
| and is expected to be removed in future revisions of this document. -- <i>end note</i>] |
| </blockquote> |
| |
| <p> |
| Note: |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2028.html">N2028: |
| Minor Modifications to the type traits Wording</a> |
| also has the intent of removing this wording from the WP. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove 20.4.9 [lib.meta.req] in its entirety from the WP. |
| </p> |
| <hr> |
| <a name="591"><h3>591. Misleading "built-in</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#New">New</a> <b>Submitter:</b> whyglinux <b>Date:</b> 8 Aug 2006</p> |
| <p> |
| 18.2.1.2 numeric_limits members [lib.numeric.limits.members] |
| Paragraph 7: |
| </p> |
| <blockquote> |
| "For built-in integer types, the number of non-sign bits in the |
| representation." |
| </blockquote> |
| |
| <p> |
| 26.1 Numeric type requirements [lib.numeric.requirements] |
| Footnote: |
| </p> |
| |
| <blockquote> |
| "In other words, value types. These include built-in arithmetic types, |
| pointers, the library class complex, and instantiations of valarray for |
| value types." |
| </blockquote> |
| |
| <p> |
| Integer types (which are bool, char, wchar_t, and the signed and |
| unsigned integer types) and arithmetic types (which are integer and |
| floating types) are all built-in types and thus there are no |
| non-built-in (that is, user-defined) integer or arithmetic types. Since |
| the redundant "built-in" in the above 2 sentences can mislead that |
| there may be built-in or user-defined integer and arithmetic types |
| (which is not correct), the "built-in" should be removed. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| </p><p> |
| 18.2.1.2 numeric_limits members [lib.numeric.limits.members] |
| Paragraph 7: |
| </p> |
| <blockquote> |
| "For <del>built-in</del> integer types, the number of non-sign bits in the |
| representation." |
| </blockquote> |
| |
| <p> |
| 26.1 Numeric type requirements [lib.numeric.requirements] |
| Footnote: |
| </p> |
| |
| <blockquote> |
| "In other words, value types. These include <del>built-in</del> arithmetic types, |
| pointers, the library class complex, and instantiations of valarray for |
| value types." |
| </blockquote> |
| <p></p> |
| <hr> |
| <a name="592"><h3>592. Incorrect treatment of rdbuf()->close() return type</h3></a><p><b>Section:</b> 27.8.1.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ifstream.members"> [lib.ifstream.members]</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 Kohlhoff <b>Date:</b> 17 Aug 2006</p> |
| <p> |
| I just spotted a minor problem in 27.8.1.7 |
| [lib.ifstream.members] para 4 and also 27.8.1.13 |
| [lib.fstream.members] para 4. In both places it says: |
| </p> |
| <blockquote> |
| <pre>void close(); |
| </pre> |
| <p> |
| Effects: Calls rdbuf()->close() and, if that function returns false, ... |
| </p> |
| </blockquote> |
| <p> |
| However, basic_filebuf::close() (27.8.1.2) returns a pointer to the |
| filebuf on success, null on failure, so I think it is meant to |
| say "if that function returns a null pointer". Oddly, it is |
| correct for basic_ofstream. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 27.8.1.7 [lib.ifstream.members], p5: |
| </p> |
| |
| <blockquote> |
| <i>Effects:</i> Calls <tt>rdbuf()->close()</tt> and, if that function |
| <ins>fails (</ins>returns <del><tt>false</tt></del> <ins>a null pointer)</ins>, |
| calls <tt>setstate(failbit)</tt> (which may throw <tt>ios_base::failure</tt> |
| (27.4.4.3)). |
| </blockquote> |
| |
| <p> |
| Change 27.8.1.13 [lib.fstream.members], p5: |
| </p> |
| |
| <blockquote> |
| <i>Effects:</i> Calls <tt>rdbuf()->close()</tt> and, if that function |
| <ins>fails (</ins>returns <del><tt>false</tt></del> <ins>a null pointer)</ins>, |
| calls <tt>setstate(failbit)</tt> (which may throw <tt>ios_base::failure</tt> |
| (27.4.4.3)). |
| </blockquote> |
| |
| <hr> |
| <a name="593"><h3>593. __STDC_CONSTANT_MACROS</h3></a><p><b>Section:</b> 18.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.cstdint"> [lib.cstdint]</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> 28 Aug 2006</p> |
| <p> |
| Clause 18.3 of the current Working Paper (N2009) deals with the new C++ headers |
| <cstdint> and <stdint.h>. These are of course based on the C99 header |
| <stdint.h>, and were part of TR1. |
| </p> |
| |
| <p> |
| Per 18.3.1/1, these headers define a number of macros and function macros. |
| While the WP does not mention __STDC_CONSTANT_MACROS in this context, C99 |
| footnotes do mention __STDC_CONSTANT_MACROS. Further, 18.3.1/2 states that "The |
| header defines all ... macros the same as C99 subclause 7.18." |
| </p> |
| |
| <p> |
| Therefore, if I wish to have the above-referenced macros and function macros |
| defined, must I #define __STDC_CONSTANT_MACROS before I #include <cstdint>, or |
| does the C++ header define these macros/function macros unconditionally? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| To put this issue to rest for C++0X, I propose the following addition to |
| 18.3.1/2 of the Working Paper N2009: |
| </p> |
| |
| <blockquote> |
| [Note: The macros defined by <cstdint> are provided unconditionally: in |
| particular, the symbols __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS |
| (mentioned in C99 footnotes 219, 220, and 222) play no role in C++. --end note] |
| </blockquote> |
| <hr> |
| <a name="594"><h3>594. Disadvantages of defining Swappable in terms of |
| CopyConstructible and Assignable</h3></a><p><b>Section:</b> 20.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.swappable"> [lib.swappable]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Niels Dekker <b>Date:</b> 2 Nov 2006</p> |
| <p> |
| It seems undesirable to define the Swappable requirement in terms of |
| CopyConstructible and Assignable requirements. And likewise, once the |
| MoveConstructible and MoveAssignable requirements (N1860) have made it |
| into the Working Draft, it seems undesirable to define the Swappable |
| requirement in terms of those requirements. Instead, it appears |
| preferable to have the Swappable requirement defined exclusively in |
| terms of the existence of an appropriate swap function. |
| </p> |
| <p> |
| Section 20.1.4 [lib.swappable] of the current Working Draft (N2009) |
| says: |
| </p><blockquote> |
| The Swappable requirement is met by satisfying one or more of the |
| following conditions: |
| <ul> |
| <li> |
| T is Swappable if T satisfies the CopyConstructible requirements |
| (20.1.3) and the Assignable requirements (23.1); |
| </li> |
| <li> |
| T is Swappable if a namespace scope function named swap exists in the |
| same namespace as the definition of T, such that the expression |
| swap(t,u) is valid and has the semantics described in Table 33. |
| </li> |
| </ul> |
| </blockquote> |
| I can think of three disadvantages of this definition: |
| <ol> |
| <li> |
| If a client's type T satisfies the first condition (T is both |
| CopyConstructible and Assignable), the client cannot stop T from |
| satisfying the Swappable requirement without stopping T from |
| satisfying the first condition. |
| <p> |
| A client might want to stop T from satisfying the Swappable |
| requirement, because swapping by means of copy construction and |
| assignment might throw an exception, and she might find a throwing |
| swap unacceptable for her type. On the other hand, she might not feel |
| the need to fully implement her own swap function for this type. In |
| this case she would want to be able to simply prevent algorithms that |
| would swap objects of type T from being used, e.g., by declaring a |
| swap function for T, and leaving this function purposely undefined. |
| This would trigger a link error, if an attempt would be made to use |
| such an algorithm for this type. For most standard library |
| implementations, this practice would indeed have the effect of |
| stopping T from satisfying the Swappable requirement. |
| </p> |
| </li> |
| <li> |
| A client's type T that does not satisfy the first condition can not be |
| made Swappable by providing a specialization of std::swap for T. |
| <p> |
| While I'm aware about the fact that people have mixed feelings about |
| providing a specialization of std::swap, it is well-defined to do so. |
| It sounds rather counter-intuitive to say that T is not Swappable, if |
| it has a valid and semantically correct specialization of std::swap. |
| Also in practice, providing such a specialization will have the same |
| effect as satisfying the Swappable requirement. |
| </p> |
| </li> |
| <li> |
| For a client's type T that satisfies both conditions of the Swappable |
| requirement, it is not specified which of the two conditions prevails. |
| After reading section 20.1.4 [lib.swappable], one might wonder whether |
| objects of T will be swapped by doing copy construction and |
| assignments, or by calling the swap function of T. |
| <p> |
| I'm aware that the intention of the Draft is to prefer calling the |
| swap function of T over doing copy construction and assignments. Still |
| in my opinion, it would be better to make this clear in the wording of |
| the definition of Swappable. |
| </p> |
| </li> |
| </ol> |
| <p></p> |
| <p> |
| I would like to have the Swappable requirement defined in such a way |
| that the following code fragment will correctly swap two objects of a |
| type T, if and only if T is Swappable: |
| </p><pre> using std::swap; |
| swap(t, u); // t and u are of type T. |
| </pre> |
| This is also the way Scott Meyers recommends calling a swap function, |
| in Effective C++, Third Edition, item 25. |
| <p></p> |
| <p> |
| Most aspects of this issue have been dealt with in a discussion on |
| comp.std.c++ about the Swappable requirement, from 13 September to 4 |
| October 2006, including valuable input by David Abrahams, Pete Becker, |
| Greg Herlihy, Howard Hinnant and others. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change section 20.1.4 [lib.swappable] as follows: |
| </p> |
| <blockquote> |
| The Swappable requirement is met by satisfying |
| <del>one or more of the following conditions:</del> |
| <ins>the following condition:</ins> |
| <ul> |
| <del> |
| <li> |
| T is Swappable if T satisfies the CopyConstructible requirements |
| (20.1.3) and the Assignable requirements (23.1); |
| </li> |
| </del> |
| <li> |
| <del> |
| T is Swappable if a namespace scope function named swap exists in the |
| same namespace as the definition of T, such that the expression |
| swap(t,u) is valid and has the semantics described in Table 33. |
| </del> |
| T is Swappable if an unqualified function call swap(t,u) is valid |
| within the namespace std, and has the semantics described in Table 33. |
| </li> |
| </ul> |
| </blockquote> |
| <hr> |
| <a name="595"><h3>595. TR1/C++0x: fabs(complex<T>) redundant / wrongly specified</h3></a><p><b>Section:</b> 26.3 <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#New">New</a> <b>Submitter:</b> Stefan Große Pawig <b>Date:</b> 24 Sep 2006</p> |
| <p> |
| TR1 introduced, in the C compatibility chapter, the function |
| fabs(complex<T>): |
| </p> |
| <blockquote><pre>----- SNIP ----- |
| 8.1.1 Synopsis [tr.c99.cmplx.syn] |
| |
| namespace std { |
| namespace tr1 { |
| [...] |
| template<class T> complex<T> fabs(const complex<T>& x); |
| } // namespace tr1 |
| } // namespace std |
| |
| [...] |
| |
| 8.1.8 Function fabs [tr.c99.cmplx.fabs] |
| |
| 1 Effects: Behaves the same as C99 function cabs, defined in |
| subclause 7.3.8.1. |
| ----- SNIP ----- |
| </pre></blockquote> |
| |
| <p> |
| The current C++0X draft document (n2009.pdf) adopted this |
| definition in chapter 26.3.1 (under the comment // 26.3.7 values) |
| and 26.3.7/7. |
| </p> |
| <p> |
| But in C99 (ISO/IEC 9899:1999 as well as the 9899:TC2 draft document |
| n1124), the referenced subclause reads |
| </p> |
| |
| <blockquote><pre>----- SNIP ----- |
| 7.3.8.1 The cabs functions |
| |
| Synopsis |
| |
| 1 #include <complex.h> |
| double cabs(double complex z); |
| float cabsf(float complex z); |
| long double cabsl(long double z); |
| |
| Description |
| |
| 2 The cabs functions compute the complex absolute value (also called |
| norm, modulus, or magnitude) of z. |
| |
| Returns |
| |
| 3 The cabs functions return the complex absolute value. |
| ----- SNIP ----- |
| </pre></blockquote> |
| |
| <p> |
| Note that the return type of the cabs*() functions is not a complex |
| type. Thus, they are equivalent to the already well established |
| template<class T> T abs(const complex<T>& x); |
| (26.2.7/2 in ISO/IEC 14882:1998, 26.3.7/2 in the current draft |
| document n2009.pdf). |
| </p> |
| <p> |
| So either the return value of fabs() is specified wrongly, or fabs() |
| does not behave the same as C99's cabs*(). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| This depends on the intention behind the introduction of fabs(). |
| </p> |
| <p> |
| If the intention was to provide a /complex/ valued function that |
| calculates the magnitude of its argument, this should be |
| explicitly specified. In TR1, the categorization under "C |
| compatibility" is definitely wrong, since C99 does not provide |
| such a complex valued function. |
| </p> |
| <p> |
| Also, it remains questionable if such a complex valued function |
| is really needed, since complex<T> supports construction and |
| assignment from real valued arguments. There is no difference |
| in observable behaviour between |
| </p> |
| <blockquote><pre> complex<double> x, y; |
| y = fabs(x); |
| complex<double> z(fabs(x)); |
| </pre></blockquote> |
| <p> |
| and |
| </p> |
| <blockquote><pre> complex<double> x, y; |
| y = abs(x); |
| complex<double> z(abs(x)); |
| </pre></blockquote> |
| <p> |
| If on the other hand the intention was to provide the intended |
| functionality of C99, fabs() should be either declared deprecated |
| or (for C++0X) removed from the standard, since the functionality |
| is already provided by the corresponding overloads of abs(). |
| </p> |
| <hr> |
| <a name="596"><h3>596. 27.8.1.3 Table 112 omits "a+" and "a+b" modes</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#New">New</a> <b>Submitter:</b> Thomas Plum <b>Date:</b> 26 Sep 2006</p> |
| <p> |
| In testing 27.8.1.3, Table 112 (in the latest N2009 draft), we invoke |
| </p> |
| <blockquote><pre> ostr.open("somename", ios_base::out | ios_base::in | ios_base::app) |
| </pre></blockquote> |
| <p> |
| and we expect the open to fail, because out|in|app is not listed in |
| Table 92, and just before the table we see very specific words: |
| </p> |
| <blockquote> |
| If mode is not some combination of flags shown in the table |
| then the open fails. |
| </blockquote> |
| <p> |
| But the corresponding table in the C standard, 7.19.5.3, provides two |
| modes "a+" and "a+b", to which the C++ modes out|in|app and |
| out|in|app|binary would presumably apply. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| We would like to argue that the intent of Table 112 was to match the |
| semantics of 7.19.5.3 and that the omission of "a+" and "a+b" was |
| unintentional. (Otherwise there would be valid and useful behaviors |
| available in C file I/O which are unavailable using C++, for no |
| valid functional reason.) |
| </p> |
| <p> |
| We further request that the missing modes be explicitly restored to |
| the WP, for inclusion in C++0x. |
| </p> |
| <hr> |
| <a name="597"><h3>597. Decimal: The notion of 'promotion' cannot be emulated by user-defined types.</h3></a><p><b>Section:</b> <font color="red">Decimal 3.2</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Open">Open</a> <b>Submitter:</b> Daveed Vandevoorde <b>Date:</b> 5 April 2006</p> |
| <p> |
| In a private email, Daveed writes: |
| </p> |
| <blockquote> |
| <p> |
| I am not familiar with the C TR, but my guess is that the |
| class type approach still won't match a built-in type |
| approach because the notion of "promotion" cannot be |
| emulated by user-defined types. |
| </p> |
| <p> |
| Here is an example: |
| </p> |
| </blockquote> |
| <pre> |
| struct S { |
| S(_Decimal32 const&); // Converting constructor |
| }; |
| void f(S); |
| |
| void f(_Decimal64); |
| |
| void g(_Decimal32 d) { |
| f(d); |
| } |
| </pre> |
| |
| <blockquote> |
| <p> |
| If _Decimal32 is a built-in type, the call f(d) will likely |
| resolve to f(_Decimal64) because that requires only a |
| promotion, whereas f(S) requires a user-defined conversion. |
| </p> |
| <p> |
| If _Decimal32 is a class type, I think the call f(d) will be |
| ambiguous because both the conversion to _Decimal64 and the |
| conversion to S will be user-defined conversions with neither |
| better than the other. |
| </p> |
| </blockquote> |
| <p> |
| Robert comments: |
| </p> |
| <p>In general, a library of arithmetic types cannot exactly emulate the |
| behavior of the intrinsic numeric types. There are several ways to tell |
| whether an implementation of the decimal types uses compiler |
| intrinisics or a library. For example: |
| </p> |
| <pre> _Decimal32 d1; |
| d1.operator+=(5); // If d1 is a builtin type, this won't compile. |
| </pre> |
| <p> |
| In preparing the decimal TR, we have three options: |
| </p> |
| <ol> |
| <li>require that the decimal types be class types</li> |
| <li>require that the decimal types be builtin types, like float and double</li> |
| <li>specify a library of class types, but allow enough implementor |
| latitude that a conforming implementation could instead provide builtin |
| types</li> |
| </ol> |
| <p> |
| We decided as a group to pursue option #3, but that approach implies |
| that implementations may not agree on the semantics of certain use |
| cases (first example, above), or on whether certain other cases are |
| well-formed (second example). Another potentially important problem is |
| that, under the present definition of POD, the decimal classes are not |
| POD types, but builtins will be. |
| </p> |
| <p>Note that neither example above implies any problems with respect to |
| C-to-C++ compatibility, since neither example can be expressed in C. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <hr> |
| <a name="598"><h3>598. Decimal: Conversion to integral should truncate, not round.</h3></a><p><b>Section:</b> <font color="red">Decimal 3.2</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Daniel Krugler <b>Date:</b> 28 May 2006</p> |
| |
| <p> |
| In a private email, Daniel writes: |
| </p> |
| <blockquote> |
| <p> |
| I would like to |
| ask, what where the reason for the decision to |
| define the semantics of the integral conversion of the decimal types, namely |
| </p> |
| <pre>"operator long long() const; |
| |
| Returns: Returns the result of the |
| conversion of *this to the type long long, as if |
| performed by the expression llrounddXX(*this)." |
| </pre> |
| <p> |
| where XX stands for either 32, 64, or 128, |
| corresponding to the proper decimal type. The |
| exact meaning of llrounddXX is not given in that |
| paper, so I compared it to the corresponding |
| definition given in C99, 2nd edition (ISO 9899), which says in 7.12.9.7 p. 2: |
| </p> |
| <p> |
| "The lround and llround functions round their |
| argument to the nearest integer value, |
| rounding halfway cases away from zero, regardless |
| of the current rounding direction. [..]" |
| </p> |
| <p> |
| Now considering the fact that integral conversion |
| of the usual floating-point types ("4.9 |
| Floating-integral conversions") has truncation |
| semantic I wonder why this conversion behaviour |
| has not been transferred for the decimal types. |
| </p> |
| </blockquote> |
| <p> |
| Robert comments: |
| </p> |
| <p> |
| Also, there is a further error in the <b>Returns:</b> clause for converting <code>decimal::decimal128</code> to <code>long long</code>. It currently calls <code>llroundd64</code>, not <code>llroundd128</code>. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the <b>Returns:</b> clause in 3.2.2.4 to: |
| </p> |
| <blockquote> |
| <b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <code>llroundd32(*this)</code> <ins>while the decimal rounding direction mode [3.5.2] <code>FE_DEC_TOWARD_ZERO</code> is in effect</ins>. |
| </blockquote> |
| <p> |
| Change the <b>Returns:</b> clause in 3.2.3.4 to: |
| </p> |
| <blockquote> |
| <b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <code>llroundd64(*this)</code> <ins>while the decimal rounding direction mode [3.5.2] <code>FE_DEC_TOWARD_ZERO</code> is in effect</ins>. |
| </blockquote> |
| <p> |
| Change the <b>Returns:</b> clause in 3.2.4.4 to: |
| </p> |
| <blockquote> |
| <b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <del><code>llroundd64(*this)</code></del> <ins><code>llroundd128(*this)</code> while the decimal rounding direction mode [3.5.2] <code>FE_DEC_TOWARD_ZERO</code> is in effect</ins>. |
| </blockquote> |
| |
| <hr> |
| <a name="599"><h3>599. Decimal: Say "octets" instead of "bytes."</h3></a><p><b>Section:</b> <font color="red">Decimal 3.1</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Daniel Krugler <b>Date:</b> 28 May 2006</p> |
| <p> |
| Daniel writes in a private email: |
| </p> |
| |
| <blockquote> |
| <p> |
| - 3.1 'Decimal type encodings' says in its note: |
| </p> |
| <p> |
| "this implies that |
| sizeof(std::decimal::decimal32) == 4, |
| sizeof(std::decimal::decimal64) == 8, and |
| sizeof(std::decimal::decimal128) == 16." |
| </p><p> |
| </p> |
| This is a wrong assertion, because the definition |
| of 'byte' in 1.7 'The C+ + memory model' of ISO |
| 14882 (2nd edition) does not specify that a byte |
| must be necessarily 8 bits large, which would be |
| necessary to compare with the specified bit sizes |
| of the types decimal32, decimal64, and decimal128. |
| <p></p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 3.1 as follows: |
| </p> |
| <blockquote> |
| <p> |
| The three decimal encoding formats defined in IEEE-754R correspond to the three decimal floating types as follows: |
| </p> |
| <ul> |
| <li> |
| decimal32 is a <em>decimal32</em> number, which is encoded in four consecutive <del>bytes</del> <ins>octets</ins> (32 bits) |
| </li> |
| <li> |
| decimal64 is a <em>decimal64</em> number, which is encoded in eight consecutive <del>bytes</del> <ins>octets</ins> (64 bits) |
| |
| </li> |
| <li> |
| decimal128 is a <em>decimal128</em> number, which is encoded in 16 consecutive <del>bytes</del> <ins>octets</ins> (128 bits) |
| </li> |
| </ul> |
| <p> |
| <del>[<i>Note:</i> this implies that <code>sizeof(std::decimal::decimal32) == 4</code>, <code>sizeof(std::decimal::decimal64) == 8</code>, and <code>sizeof(std::decimal::decimal128) == 16</code>. <i>--end note</i>]</del> |
| </p> |
| </blockquote> |
| <hr> |
| <a name="600"><h3>600. Decimal: Wrong parameters for wcstod* functions</h3></a><p><b>Section:</b> <font color="red">Decimal 3.9</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Daniel Krugler <b>Date:</b> 28 May 2006</p> |
| <p> |
| Daniel writes: |
| </p> |
| <blockquote> |
| - 3.9.1 'Additions to <cwchar>' provides wrong |
| signatures to the wcstod32, wcstod64, and |
| wcstod128 functions ([the parameters have type pointer-to-] char instead of wchar_t). |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change "3.9.1 Additions to <code><cwchar></code> synopsis" to: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| // 3.9.2 wcstod functions: |
| decimal32 wcstod32 (const <del>char</del> <ins>wchar_t</ins> * nptr, <del>char</del> <ins>wchar_t</ins> ** endptr); |
| decimal64 wcstod64 (const <del>char</del> <ins>wchar_t</ins> * nptr, <del>char</del> <ins>wchar_t</ins> ** endptr); |
| decimal128 wcstod128 (const <del>char</del> <ins>wchar_t</ins> * nptr, <del>char</del> <ins>wchar_t</ins> ** endptr); |
| } |
| } |
| </pre> |
| <hr> |
| <a name="601"><h3>601. Decimal: numeric_limits typos</h3></a><p><b>Section:</b> <font color="red">Decimal 3.3</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Daniel Krugler <b>Date:</b> 28 May 2006</p> |
| <p> |
| Daniel writes in a private email: |
| </p> |
| |
| <blockquote> |
| <p> |
| - 3.3 'Additions to header <limits>' contains two |
| errors in the specialisation of numeric_limits<decimal::decimal128>: |
| </p> |
| <ol> |
| <li>The static member max() returns DEC128_MIN, this should be DEC128_MAX.</li> |
| <li>The static member digits is assigned to 384, |
| this should be 34 (Probably mixed up with the |
| max. exponent for decimal::decimal64).</li> |
| </ol> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In "3.3 Additions to header <code><limits></code>" change numeric_limits<decimal::decimal128> as follows: |
| </p> |
| <pre> template<> class numeric_limits<decimal::decimal128> { |
| public: |
| static const bool is_specialized = true; |
| |
| static decimal::decimal128 min() throw() { return DEC128_MIN; } |
| static decimal::decimal128 max() throw() { return <del>DEC128_MIN;</del> <ins>DEC128_MAX;</ins> } |
| |
| static const int digits = <del>384</del> <ins>34</ins>; |
| /* ... */ |
| </pre> |
| <hr> |
| <a name="602"><h3>602. Decimal: "generic floating type" not defined.</h3></a><p><b>Section:</b> <font color="red">Decimal 3</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Daniel Krugler <b>Date:</b> 28 May 2006</p> |
| <p> |
| The document uses the term "generic floating types," but defines it nowhere. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the first paragraph of "3 Decimal floating-point types" as follows: |
| </p> |
| <blockquote> |
| This Technical Report introduces three decimal floating-point types, named |
| decimal32, decimal64, and decimal128. The set of values of type decimal32 is a |
| subset of the set of values of type decimal64; the set of values of the type |
| decimal64 is a subset of the set of values of the type decimal128. Support for |
| decimal128 is optional. <ins>These types supplement the Standard C++ types |
| <code>float</code>, <code>double</code>, and <code>long double</code>, which are |
| collectively described as the <i>basic floating types</i></ins>. |
| </blockquote> |
| <hr> |
| <a name="603"><h3>603. Decimal: Trivially simplifying decimal classes.</h3></a><p><b>Section:</b> <font color="red">Decimal 3</font> <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> 28 May 2006</p> |
| <p>In c++std-lib-17198, Martin writes:</p> |
| |
| <blockquote> |
| Each of the three classes proposed in the paper (decimal32, decimal64, |
| and decimal128) explicitly declares and specifies the semantics of its |
| copy constructor, copy assignment operator, and destructor. Since the |
| semantics of all three functions are identical to the trivial versions |
| implicitly generated by the compiler in the absence of any declarations |
| it is safe to drop them from the spec. This change would make the |
| proposed classes consistent with other similar classes already in the |
| standard (e.g., std::complex). |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change "3.2.2 Class <code>decimal32</code>" as follows: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| class decimal32 { |
| public: |
| // 3.2.2.1 construct/copy/destroy: |
| decimal32(); |
| <del>decimal32(const decimal32 & d32);</del> |
| <del>decimal32 & operator=(const decimal32 & d32);</del> |
| <del>~decimal32();</del> |
| /* ... */ |
| </pre> |
| <p> |
| Change "3.2.2.1 construct/copy/destroy" as follows: |
| </p> |
| <pre> decimal32(); |
| |
| Effects: Constructs an object of type decimal32 with the value 0; |
| |
| <del>decimal32(const decimal32 & d32);</del> |
| <del>decimal32 & operator=(const decimal32 & d32);</del> |
| |
| <del>Effects: Copies an object of type decimal32.</del> |
| |
| <del>~decimal32();</del> |
| |
| <del>Effects: Destroys an object of type decimal32.</del> |
| |
| </pre> |
| <p> |
| Change "3.2.3 Class <code>decimal64</code>" as follows: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| class decimal64 { |
| public: |
| // 3.2.3.1 construct/copy/destroy: |
| decimal64(); |
| <del>decimal64(const decimal64 & d64);</del> |
| <del>decimal64 & operator=(const decimal64 & d64);</del> |
| <del>~decimal64();</del> |
| /* ... */ |
| </pre> |
| <p> |
| Change "3.2.3.1 construct/copy/destroy" as follows: |
| </p> |
| <pre> decimal64(); |
| |
| Effects: Constructs an object of type decimal64 with the value 0; |
| |
| <del>decimal64(const decimal64 & d64);</del> |
| <del>decimal64 & operator=(const decimal64 & d64);</del> |
| |
| <del>Effects: Copies an object of type decimal64.</del> |
| |
| <del>~decimal64();</del> |
| |
| <del>Effects: Destroys an object of type decimal64.</del> |
| |
| </pre> |
| <p> |
| Change "3.2.4 Class <code>decimal128</code>" as follows: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| class decimal128 { |
| public: |
| // 3.2.4.1 construct/copy/destroy: |
| decimal128(); |
| <del>decimal128(const decimal128 & d128);</del> |
| <del>decimal128 & operator=(const decimal128 & d128);</del> |
| <del>~decimal128();</del> |
| /* ... */ |
| </pre> |
| <p> |
| Change "3.2.4.1 construct/copy/destroy" as follows: |
| </p> |
| <pre> decimal128(); |
| |
| Effects: Constructs an object of type decimal128 with the value 0; |
| |
| <del>decimal128(const decimal128 & d128);</del> |
| <del>decimal128 & operator=(const decimal128 & d128);</del> |
| |
| <del>Effects: Copies an object of type decimal128.</del> |
| |
| <del>~decimal128();</del> |
| |
| <del>Effects: Destroys an object of type decimal128.</del> |
| |
| </pre> |
| <hr> |
| <a name="604"><h3>604. Decimal: Storing a reference to a facet unsafe.</h3></a><p><b>Section:</b> <font color="red">Decimal 3</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Review">Review</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 May 2006</p> |
| <p> |
| In c++std-lib-17197, Martin writes: |
| </p> |
| <blockquote> |
| The extended_num_get and extended_num_put facets are designed |
| to store a reference to a num_get or num_put facet which the |
| extended facets delegate the parsing and formatting of types |
| other than decimal. One form of the extended facet's ctor (the |
| default ctor and the size_t overload) obtains the reference |
| from the global C++ locale while the other form takes this |
| reference as an argument. |
| </blockquote> |
| <blockquote> |
| The problem with storing a reference to a facet in another |
| object (as opposed to storing the locale object in which the |
| facet is installed) is that doing so bypasses the reference |
| counting mechanism designed to prevent a facet that is still |
| being referenced (i.e., one that is still installed in some |
| locale) from being destroyed when another locale that contains |
| it is destroyed. Separating a facet reference from the locale |
| it comes from van make it cumbersome (and in some cases might |
| even make it impossible) for programs to prevent invalidating |
| the reference. (The danger of this design is highlighted in |
| the paper.) |
| </blockquote> |
| <blockquote> |
| This problem could be easily avoided by having the extended |
| facets store a copy of the locale from which they would extract |
| the base facet either at construction time or when needed. To |
| make it possible, the forms of ctors of the extended facets that |
| take a reference to the base facet would need to be changed to |
| take a locale argument instead. |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1. Change the <code>extended_num_get</code> synopsis in 3.10.2 as follows: |
| </p> |
| <pre> extended_num_get(const <del>std::num_get<charT, InputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| |
| /* ... */ |
| |
| <del>// <i>const std::num_get<charT, InputIterator> & <b>base</b></i>; <i><b>exposition only</b></i></del> |
| <ins>// <i>std::locale <b>baseloc</b></i>; <i><b>exposition only</b></i></ins> |
| </pre> |
| <p> |
| 2. Change the description of the above constructor in 3.10.2.1: |
| </p> |
| <pre> extended_num_get(const <del>std::num_get<charT, InputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| |
| </pre> |
| <blockquote> |
| <p> |
| <b>Effects:</b> Constructs an <code>extended_num_get</code> facet as if by: |
| </p> |
| <pre> extended_num_get(const <del>std::num_get<charT, InputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0) |
| : facet(<i>refs</i>), <i>base<ins>loc</ins></i>(<i>b</i>) |
| { /* ... */ } |
| |
| </pre> |
| <p> |
| <del><b>Notes:</b> Care must be taken by the implementation to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_get</code> facet.</del> |
| </p> |
| </blockquote> |
| <p> |
| 3. Change the <b>Returns:</b> clause for <code>do_get(iter_type, iter_type, ios_base &, ios_base::iostate &, bool &) const</code>, <i>et al</i> to |
| </p> |
| <blockquote> |
| <b>Returns:</b> <code><del><i>base</i></del> <ins>std::use_facet<std::num_get<charT, InputIterator> >(<i>baseloc</i>)</ins>.get(<i>in</i>, <i>end</i>, <i>str</i>, <i>err</i>, <i>val</i>)</code>. |
| </blockquote> |
| <p> |
| 4. Change the <code>extended_num_put</code> synopsis in 3.10.3 as follows: |
| </p> |
| <pre> extended_num_put(const <del>std::num_put<charT, OutputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| |
| /* ... */ |
| |
| <del>// <i>const std::num_put<charT, OutputIterator> & <b>base</b></i>; <i><b>exposition only</b></i></del> |
| <ins>// <i>std::locale <b>baseloc</b></i>; <i><b>exposition only</b></i></ins> |
| </pre> |
| <p> |
| 5. Change the description of the above constructor in 3.10.3.1: |
| </p> |
| <pre> extended_num_put(const <del>std::num_put<charT, OutputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| </pre> |
| <blockquote> |
| <p> |
| <b>Effects:</b> Constructs an <code>extended_num_put</code> facet as if by: |
| </p> |
| <pre> extended_num_put(const <del>std::num_put<charT, OutputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0) |
| : facet(<i>refs</i>), <i>base<ins>loc</ins></i>(<i>b</i>) |
| { /* ... */ } |
| |
| </pre> |
| <p> |
| <del><b>Notes:</b> Care must be taken by the implementation to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_put</code> facet.</del> |
| </p> |
| </blockquote> |
| <p> |
| 6. Change the <b>Returns:</b> clause for <code>do_put(iter_type, ios_base &, char_type, bool &) const</code>, <i>et al</i> to |
| </p> |
| <blockquote> |
| <b>Returns:</b> <code><del><i>base</i></del> <ins>std::use_facet<std::num_put<charT, OutputIterator> >(<i>baseloc</i>)</ins>.put(<i>s</i>, <i>f</i>, <i>fill</i>, <i>val</i>)</code>. |
| </blockquote> |
| |
| <p><i>[ |
| Redmond: We would prefer to rename "extended" to "decimal". |
| ]</i></p> |
| |
| <hr> |
| <a name="605"><h3>605. Decimal: <decfloat.h> doesn't live here anymore.</h3></a><p><b>Section:</b> <font color="red">Decimal 3.4</font> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Robert Klarer <b>Date:</b> 17 October 2006</p> |
| <p>In Berlin, WG14 decided to drop the <decfloat.h> header. The |
| contents of that header have been moved into <float.h>. For the |
| sake of C compatibility, we should make corresponding changes. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1. Change the heading of subclause 3.4, "Headers <code><cdecfloat></code> and <code><decfloat.h></code>" to "Additions to headers <code><cfloat></code> and <code><float.h></code>." |
| </p> |
| <p> |
| 2. Change the text of subclause 3.4 as follows: |
| </p> |
| <blockquote> |
| <p> |
| <del>The standard C++ headers <code><cfloat></code> and <code><float.h></code> define characteristics of the floating-point types <code>float</code>, <code>double</code>, and <code>long double</code>. Their contents remain unchanged by this Technical Report.</del> |
| </p> |
| <p> |
| <del>Headers <code><cdecfloat></code> and <code><decfloat.h></code> define characteristics of the decimal floating-point types <code>decimal32</code>, <code>decimal64</code>, and <code>decimal128</code>. As well, <code><decfloat.h></code> defines the convenience typedefs <code>_Decimal32</code>, <code>_Decimal64</code>, and <code>_Decimal128</code>, for compatibilty with the C programming language.</del> |
| </p> |
| <p> |
| <ins>The header <code><cfloat></code> is described in [tr.c99.cfloat]. The header <code><float.h></code> |
| is described in [tr.c99.floath]. These headers are extended by this |
| Technical Report to define characteristics of the decimal |
| floating-point types <code>decimal32</code>, <code>decimal64</code>, and <code>decimal128</code>. As well, <code><float.h></code> is extended to define the convenience typedefs <code>_Decimal32</code>, <code>_Decimal64</code>, and <code>_Decimal128</code> for compatibility with the C programming language.</ins> |
| </p> |
| </blockquote> |
| <p> |
| 3. Change the heading of subclause 3.4.1, "Header <code><cdecfloat></code> synopsis" to "Additions to header <code><cfloat></code> synopsis." |
| </p> |
| <p> |
| 4. Change the heading of subclause 3.4.2, "Header <code><decfloat.h></code> synopsis" to "Additions to header <code><float.h></code> synopsis." |
| </p> |
| <p> |
| 5. Change the contents of 3.4.2 as follows: |
| </p> |
| <pre> <del>#include <cdecfloat></del> |
| |
| // <i>C-compatibility convenience typedefs:</i> |
| |
| typedef std::decimal::decimal32 _Decimal32; |
| typedef std::decimal::decimal64 _Decimal64; |
| typedef std::decimal::decimal128 _Decimal128; |
| </pre> |
| |
| <hr> |
| <a name="606"><h3>606. Decimal: allow narrowing conversions</h3></a><p><b>Section:</b> <font color="red">Decimal 3.2</font> <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> 15 June 2006</p> |
| <p> |
| In c++std-lib-17205, Martin writes: |
| </p> |
| <blockquote> |
| ...was it a deliberate design choice to make narrowing assignments |
| ill-formed while permitting narrowing compound assignments? For |
| instance: |
| </blockquote> |
| <pre> decimal32 d32; |
| decimal64 d64; |
| |
| d32 = 64; // error |
| d32 += 64; // okay |
| </pre> |
| <p> |
| In c++std-lib-17229, Robert responds: |
| </p> |
| <blockquote>It is a vestige of an old idea that I forgot to remove from |
| the paper. Narrowing assignments should be permitted. The bug is that |
| the converting constructors that cause narrowing should not be |
| explicit. Thanks for pointing this out. |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1. In "3.2.2 Class <code>decimal32</code>" synopsis, remove the <code>explicit</code> specifier from the narrowing conversions: |
| </p> |
| <pre> // <i>3.2.2.2 conversion from floating-point type:</i> |
| <del>explicit</del> decimal32(decimal64 <i>d64</i>); |
| <del>explicit</del> decimal32(decimal128 <i>d128</i>); |
| </pre> |
| <p> |
| 2. Do the same thing in "3.2.2.2. Conversion from floating-point type." |
| </p> |
| <p> |
| 3. In "3.2.3 Class <code>decimal64</code>" synopsis, remove the <code>explicit</code> specifier from the narrowing conversion: |
| </p> |
| <pre> // <i>3.2.3.2 conversion from floating-point type:</i> |
| <del>explicit</del> decimal64(decimal128 <i>d128</i>); |
| </pre> |
| <p> |
| 4. Do the same thing in "3.2.3.2. Conversion from floating-point type." |
| </p> |
| |
| <p><i>[ |
| Redmond: We prefer explicit conversions for narrowing and implicit for widening. |
| ]</i></p> |
| |
| <hr> |
| <a name="607"><h3>607. Concern about short seed vectors</h3></a><p><b>Section:</b> 26.4.7.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.rand.dist.iunif"> [lib.rand.dist.iunif]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Charles Karney <b>Date:</b> 26 Oct 2006</p> |
| <p> |
| Short seed vectors of 32-bit quantities all result in different states. However |
| this is not true of seed vectors of 16-bit (or smaller) quantities. For example |
| these two seeds |
| </p> |
| |
| <blockquote><pre>unsigned short seed = {1, 2, 3}; |
| unsigned short seed = {1, 2, 3, 0}; |
| </pre></blockquote> |
| |
| <p> |
| both pack to |
| </p> |
| |
| <blockquote><pre>unsigned seed = {0x20001, 0x3}; |
| </pre></blockquote> |
| |
| <p> |
| yielding the same state. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 26.4.7.1[rand.util.seedseq]/8a, replace |
| </p> |
| |
| <blockquote> |
| <p> |
| Set <tt>begin[0]</tt> to <tt>5489 + <del>s</del><ins>N</ins></tt>. |
| </p> |
| <p> |
| where <tt>N</tt> is the bit length of the sequence used to construct the |
| seed_seq in 26.4.7.1/6 [rand.util.seedseq]. (This quantity is called <tt>n</tt> |
| in 26.4.7.1/6 [rand.util.seedseq], but <tt>n</tt> has a different meaning in |
| 26.4.7.1/8 [rand.util.seedseq]. We have <tt>32^(s-1) < N <= 32^s</tt>.) Now |
| </p> |
| |
| <blockquote><pre>unsigned short seed = {1, 2, 3, 0}; |
| unsigned seed = {0x20001, 0x3}; |
| </pre></blockquote> |
| |
| <p> |
| are equivalent (<tt>N = 64</tt>), but |
| </p> |
| |
| <blockquote><pre>unsigned short seed = {1, 2, 3}; |
| </pre></blockquote> |
| |
| <p> |
| gives a distinct state (<tt>N = 48</tt>). |
| </p> |
| </blockquote> |
| |
| <hr> |
| <a name="608"><h3>608. Unclear seed_seq construction details</h3></a><p><b>Section:</b> 26.4.7.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.rand.dist.iunif"> [lib.rand.dist.iunif]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#New">New</a> <b>Submitter:</b> Charles Karney <b>Date:</b> 26 Oct 2006</p> |
| <p> |
| In 26.4.7.1 [rand.util.seedseq] /6, the order of packing the inputs into b and the |
| treatment of signed quantities is unclear. Better to spell it out. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <blockquote><pre>b = sum( unsigned(begin[i]) 2^(w i), 0 <= i < end-begin ) |
| </pre></blockquote> |
| |
| <p> |
| where <tt>w</tt> is the bit-width of the InputIterator. |
| </p> |
| <hr> |
| <a name="609"><h3>609. missing static const</h3></a><p><b>Section:</b> 26.4.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.rand.eng.mers"> [lib.rand.eng.mers]</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 E. Brown <b>Date:</b> 2 Nov 2006</p> |
| <p> |
| In preparing N2111, an error on my part resulted in the omission of the |
| following line from the template synopsis in the cited section: |
| </p> |
| |
| <blockquote><pre>static const size_t word_size = w; |
| </pre></blockquote> |
| |
| <p> |
| (This same constant is found, for example, in 26.4.3.3 [rand.eng.sub].) |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the above declaration as the first line after the comment in [rand.adapt.ibits] p4: |
| </p> |
| |
| <blockquote><pre>// engine characteristics |
| <ins>static const size_t word_size = w;</ins> |
| </pre></blockquote> |
| |
| <p> |
| and accept my apologies for the oversight. |
| </p> |
| <p>----- End of document -----</p> |
| </body></html> |