| <!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 Defect Report 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">N2131=06-0201</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 Defect Report 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-active.html">Library Active Issues 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>This document contains only library issues which have been closed |
| by the Library Working Group (LWG) after being found to be defects |
| in the standard. That is, issues which have a status of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a>, or <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#RR">RR</a>. See the |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html">Library Closed Issues List</a> for issues closed as non-defects. See the |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html">Library Active Issues List</a> for active issues and more information. The |
| introductory material in that document also applies to this |
| document.</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>Defect Reports</h2> |
| <hr> |
| <a name="1"><h3>1. C library linkage editing oversight</h3></a><p><b>Section:</b> 17.4.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.using.linkage"> [lib.using.linkage]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 16 Nov 1997</p> |
| <p>The change specified in the proposed resolution below did not make |
| it into the Standard. This change was accepted in principle at the |
| London meeting, and the exact wording below was accepted at the |
| Morristown meeting.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 17.4.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.using.linkage"> [lib.using.linkage]</a> paragraph 2 |
| from:</p> |
| |
| <blockquote> |
| <p>It is unspecified whether a name from the Standard C library |
| declared with external linkage has either extern "C" or |
| extern "C++" linkage.</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Whether a name from the Standard C library declared with external |
| linkage has extern "C" or extern "C++" linkage |
| is implementation defined. It is recommended that an implementation |
| use extern "C++" linkage for this purpose.</p> |
| </blockquote> |
| <hr> |
| <a name="3"><h3>3. Atexit registration during atexit() call is not described</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#TC">TC</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 12 Dec 1997</p> |
| <p>We appear not to have covered all the possibilities of |
| exit processing with respect to |
| atexit registration. <br> |
| <br> |
| Example 1: (C and C++)</p> |
| |
| <pre> #include <stdlib.h> |
| void f1() { } |
| void f2() { atexit(f1); } |
| |
| int main() |
| { |
| atexit(f2); // the only use of f2 |
| return 0; // for C compatibility |
| }</pre> |
| |
| <p>At program exit, f2 gets called due to its registration in |
| main. Running f2 causes f1 to be newly registered during the exit |
| processing. Is this a valid program? If so, what are its |
| semantics?</p> |
| |
| <p> |
| Interestingly, neither the C standard, nor the C++ draft standard nor |
| the forthcoming C9X Committee Draft says directly whether you can |
| register a function with atexit during exit processing.</p> |
| |
| <p> |
| All 3 standards say that functions are run in reverse order of their |
| registration. Since f1 is registered last, it ought to be run first, |
| but by the time it is registered, it is too late to be first.</p> |
| |
| <p>If the program is valid, the standards are self-contradictory about |
| its semantics.</p> |
| |
| <p>Example 2: (C++ only)</p> |
| |
| <pre> |
| void F() { static T t; } // type T has a destructor |
| |
| int main() |
| { |
| atexit(F); // the only use of F |
| } |
| </pre> |
| |
| <p>Function F registered with atexit has a local static variable t, |
| and F is called for the first time during exit processing. A local |
| static object is initialized the first time control flow passes |
| through its definition, and all static objects are destroyed during |
| exit processing. Is the code valid? If so, what are its semantics?</p> |
| |
| <p> |
| Section 18.3 "Start and termination" says that if a function |
| F is registered with atexit before a static object t is initialized, F |
| will not be called until after t's destructor completes.</p> |
| |
| <p> |
| In example 2, function F is registered with atexit before its local |
| static object O could possibly be initialized. On that basis, it must |
| not be called by exit processing until after O's destructor |
| completes. But the destructor cannot be run until after F is called, |
| since otherwise the object could not be constructed in the first |
| place.</p> |
| |
| <p>If the program is valid, the standard is self-contradictory about |
| its semantics.</p> |
| |
| <p>I plan to submit Example 1 as a public comment on the C9X CD, with |
| a recommendation that the results be undefined. (Alternative: make it |
| unspecified. I don't think it is worthwhile to specify the case where |
| f1 itself registers additional functions, each of which registers |
| still more functions.)</p> |
| |
| <p>I think we should resolve the situation in the whatever way the C |
| committee decides. </p> |
| |
| <p>For Example 2, I recommend we declare the results undefined.</p> |
| |
| <p><i>[See reflector message lib-6500 for further discussion.]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change section 18.3/8 from:</p> |
| <blockquote> |
| First, objects with static storage duration are destroyed and |
| functions registered by calling atexit are called. Objects with |
| static storage duration are destroyed in the reverse order of the |
| completion of their constructor. (Automatic objects are not |
| destroyed as a result of calling exit().) Functions registered with |
| atexit are called in the reverse order of their registration. A |
| function registered with atexit before an object obj1 of static |
| storage duration is initialized will not be called until obj1's |
| destruction has completed. A function registered with atexit after |
| an object obj2 of static storage duration is initialized will be |
| called before obj2's destruction starts. |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| First, objects with static storage duration are destroyed and |
| functions registered by calling atexit are called. Non-local objects |
| with static storage duration are destroyed in the reverse order of |
| the completion of their constructor. (Automatic objects are not |
| destroyed as a result of calling exit().) Functions registered with |
| atexit are called in the reverse order of their registration, except |
| that a function is called after any previously registered functions |
| that had already been called at the time it was registered. A |
| function registered with atexit before a non-local object obj1 of |
| static storage duration is initialized will not be called until |
| obj1's destruction has completed. A function registered with atexit |
| after a non-local object obj2 of static storage duration is |
| initialized will be called before obj2's destruction starts. A local |
| static object obj3 is destroyed at the same time it would be if a |
| function calling the obj3 destructor were registered with atexit at |
| the completion of the obj3 constructor. |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>See 99-0039/N1215, October 22, 1999, by Stephen D. Clamage for the analysis |
| supporting to the proposed resolution.</p> |
| <hr> |
| <a name="5"><h3>5. String::compare specification questionable</h3></a><p><b>Section:</b> 21.3.6.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::compare"> [lib.string::compare]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Jack Reeves <b>Date:</b> 11 Dec 1997</p> |
| <p>At the very end of the basic_string class definition is the signature: int |
| compare(size_type pos1, size_type n1, const charT* s, size_type n2 = npos) const; In the |
| following text this is defined as: returns |
| basic_string<charT,traits,Allocator>(*this,pos1,n1).compare( |
| basic_string<charT,traits,Allocator>(s,n2); </p> |
| |
| <p>Since the constructor basic_string(const charT* s, size_type n, const Allocator& a |
| = Allocator()) clearly requires that s != NULL and n < npos and further states that it |
| throws length_error if n == npos, it appears the compare() signature above should always |
| throw length error if invoked like so: str.compare(1, str.size()-1, s); where 's' is some |
| null terminated character array. </p> |
| |
| <p>This appears to be a typo since the obvious intent is to allow either the call above or |
| something like: str.compare(1, str.size()-1, s, strlen(s)-1); </p> |
| |
| <p>This would imply that what was really intended was two signatures int compare(size_type |
| pos1, size_type n1, const charT* s) const int compare(size_type pos1, size_type n1, const |
| charT* s, size_type n2) const; each defined in terms of the corresponding constructor. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the compare signature in 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a> |
| (at the very end of the basic_string synopsis) which reads:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos1, size_type n1,<br> |
| const charT* s, |
| size_type n2 = npos) const;</tt></p> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos1, size_type n1,<br> |
| const charT* s) const;<br> |
| int compare(size_type pos1, size_type n1,<br> |
| const charT* s, |
| size_type n2) const;</tt></p> |
| </blockquote> |
| |
| <p>Replace the portion of 21.3.6.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::compare"> [lib.string::compare]</a> |
| paragraphs 5 and 6 which read:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos, size_type n1,<br> |
| charT * s, size_type n2 |
| = npos) const;<br> |
| </tt>Returns:<tt><br> |
| basic_string<charT,traits,Allocator>(*this, pos, n1).compare(<br> |
| |
| basic_string<charT,traits,Allocator>( s, n2))</tt></p> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos, size_type n1,<br> |
| const charT * s) const;<br> |
| </tt>Returns:<tt><br> |
| basic_string<charT,traits,Allocator>(*this, pos, n1).compare(<br> |
| |
| basic_string<charT,traits,Allocator>( s ))<br> |
| <br> |
| int compare(size_type pos, size_type n1,<br> |
| const charT * s, |
| size_type n2) const;<br> |
| </tt>Returns:<tt><br> |
| basic_string<charT,traits,Allocator>(*this, pos, n1).compare(<br> |
| |
| basic_string<charT,traits,Allocator>( s, n2))</tt></p> |
| </blockquote> |
| |
| <p>Editors please note that in addition to splitting the signature, the third argument |
| becomes const, matching the existing synopsis.</p> |
| <p><b>Rationale:</b></p> |
| <p>While the LWG dislikes adding signatures, this is a clear defect in |
| the Standard which must be fixed. The same problem was also |
| identified in issues 7 (item 5) and 87.</p> |
| <hr> |
| <a name="7"><h3>7. String clause minor problems</h3></a><p><b>Section:</b> 21 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.strings"> [lib.strings]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 15 Dec 1997</p> |
| <p>(1) In 21.3.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::insert"> [lib.string::insert]</a>, the description of template |
| <class InputIterator> insert(iterator, InputIterator, |
| InputIterator) makes no sense. It refers to a member function that |
| doesn't exist. It also talks about the return value of a void |
| function. </p> |
| |
| <p>(2) Several versions of basic_string::replace don't appear in the |
| class synopsis. </p> |
| |
| <p>(3) basic_string::push_back appears in the synopsis, but is never |
| described elsewhere. In the synopsis its argument is const charT, |
| which doesn't makes much sense; it should probably be charT, or |
| possible const charT&. </p> |
| |
| <p>(4) basic_string::pop_back is missing. </p> |
| |
| <p>(5) int compare(size_type pos, size_type n1, charT* s, size_type n2 |
| = npos) make no sense. First, it's const charT* in the synopsis and |
| charT* in the description. Second, given what it says in RETURNS, |
| leaving out the final argument will always result in an exception |
| getting thrown. This is paragraphs 5 and 6 of |
| 21.3.6.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::compare"> [lib.string::compare]</a></p> |
| |
| <p>(6) In table 37, in section 21.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits.require"> [lib.char.traits.require]</a>, |
| there's a note for X::move(s, p, n). It says "Copies correctly |
| even where p is in [s, s+n)". This is correct as far as it goes, |
| but it doesn't go far enough; it should also guarantee that the copy |
| is correct even where s in in [p, p+n). These are two orthogonal |
| guarantees, and neither one follows from the other. Both guarantees |
| are necessary if X::move is supposed to have the same sort of |
| semantics as memmove (which was clearly the intent), and both |
| guarantees are necessary if X::move is actually supposed to be |
| useful. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>ITEM 1: In 21.3.5.4 [lib.string::insert], change paragraph 16 to <br> |
| <br> |
| EFFECTS: Equivalent to insert(p - begin(), basic_string(first, last)).<br> |
| <br> |
| ITEM 2: Not a defect; the Standard is clear.. There are ten versions of replace() in |
| the synopsis, and ten versions in 21.3.5.6 [lib.string::replace].<br> |
| <br> |
| ITEM 3: Change the declaration of push_back in the string synopsis (21.3, |
| [lib.basic.string]) from:</p> |
| |
| <p> void push_back(const charT)<br> |
| <br> |
| to<br> |
| <br> |
| void push_back(charT)<br> |
| <br> |
| Add the following text immediately after 21.3.5.2 [lib.string::append], paragraph 10.<br> |
| <br> |
| void basic_string::push_back(charT c);<br> |
| EFFECTS: Equivalent to append(static_cast<size_type>(1), c);<br> |
| <br> |
| ITEM 4: Not a defect. The omission appears to have been deliberate.<br> |
| <br> |
| ITEM 5: Duplicate; see issue 5 (and 87).<br> |
| <br> |
| ITEM 6: In table 37, Replace:<br> |
| <br> |
| "Copies correctly even where p is in [s, s+n)."<br> |
| <br> |
| with:<br> |
| <br> |
| "Copies correctly even where the ranges [p, p+n) and [s, |
| s+n) overlap."</p> |
| <hr> |
| <a name="8"><h3>8. Locale::global lacks guarantee</h3></a><p><b>Section:</b> 22.1.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.statics"> [lib.locale.statics]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 24 Dec 1997</p> |
| <p>It appears there's an important guarantee missing from clause |
| 22. We're told that invoking locale::global(L) sets the C locale if L |
| has a name. However, we're not told whether or not invoking |
| setlocale(s) sets the global C++ locale. </p> |
| |
| <p>The intent, I think, is that it should not, but I can't find any |
| such words anywhere. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a sentence at the end of 22.1.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.statics"> [lib.locale.statics]</a>, |
| paragraph 2: </p> |
| |
| <blockquote> |
| <p>No library function other than <tt>locale::global()</tt> shall affect |
| the value returned by <tt>locale()</tt>. </p> |
| |
| </blockquote> |
| <hr> |
| <a name="9"><h3>9. Operator new(0) calls should not yield the same pointer</h3></a><p><b>Section:</b> 18.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete"> [lib.new.delete]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 4 Jan 1998</p> |
| <p>Scott Meyers, in a comp.std.c++ posting: I just noticed that |
| section 3.7.3.1 of CD2 seems to allow for the possibility that all |
| calls to operator new(0) yield the same pointer, an implementation |
| technique specifically prohibited by ARM 5.3.3.Was this prohibition |
| really lifted? Does the FDIS agree with CD2 in the regard? [Issues |
| list maintainer's note: the IS is the same.]</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the last paragraph of 3.7.3 from:</p> |
| <blockquote> |
| <p>Any allocation and/or deallocation functions defined in a C++ program shall |
| conform to the semantics specified in 3.7.3.1 and 3.7.3.2.</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Any allocation and/or deallocation functions defined in a C++ program, |
| including the default versions in the library, shall conform to the semantics |
| specified in 3.7.3.1 and 3.7.3.2.</p> |
| </blockquote> |
| <p>Change 3.7.3.1/2, next-to-last sentence, from :</p> |
| <blockquote> |
| <p>If the size of the space requested is zero, the value returned shall not be |
| a null pointer value (4.10).</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Even if the size of the space requested is zero, the request can fail. If |
| the request succeeds, the value returned shall be a non-null pointer value |
| (4.10) p0 different from any previously returned value p1, unless that value |
| p1 was since passed to an operator delete.</p> |
| </blockquote> |
| <p>5.3.4/7 currently reads:</p> |
| <blockquote> |
| <p>When the value of the expression in a direct-new-declarator is zero, the |
| allocation function is called to allocate an array with no elements. The |
| pointer returned by the new-expression is non-null. [Note: If the library |
| allocation function is called, the pointer returned is distinct from the |
| pointer to any other object.]</p> |
| </blockquote> |
| <p>Retain the first sentence, and delete the remainder.</p> |
| <p>18.5.1 currently has no text. Add the following:</p> |
| <blockquote> |
| <p>Except where otherwise specified, the provisions of 3.7.3 apply to the |
| library versions of operator new and operator delete.</p> |
| </blockquote> |
| <p>To 18.5.1.3, add the following text:</p> |
| <blockquote> |
| <p>The provisions of 3.7.3 do not apply to these reserved placement forms of |
| operator new and operator delete.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis |
| supporting to the proposed resolution.</p> |
| <hr> |
| <a name="11"><h3>11. Bitset minor problems</h3></a><p><b>Section:</b> 23.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.template.bitset"> [lib.template.bitset]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 22 Jan 1998</p> |
| <p>(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is |
| not documented in 23.3.5.2. </p> |
| |
| <p>(2) The class synopsis only gives a single signature for bitset<>::operator[], |
| reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded |
| on const. reference operator[](size_t pos); bool operator[](size_t pos) const. </p> |
| |
| <p>(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before |
| trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should |
| go in the Effects clause.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>ITEMS 1 AND 2:<br> |
| <br> |
| In the bitset synopsis (23.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.template.bitset"> [lib.template.bitset]</a>), |
| replace the member function <br> |
| <br> |
| <tt> reference operator[](size_t pos);<br> |
| </tt><br> |
| with the two member functions<br> |
| <br> |
| <tt> bool operator[](size_t pos) const; <br> |
| reference operator[](size_t pos); <br> |
| </tt><br> |
| Add the following text at the end 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>, |
| immediately after paragraph 45:</p> |
| |
| <blockquote> |
| <p><tt>bool operator[](size_t pos) const;</tt><br> |
| Requires: pos is valid<br> |
| Throws: nothing<br> |
| Returns: <tt>test(pos)</tt><br> |
| <br> |
| <tt>bitset<N>::reference operator[](size_t pos);</tt> <br> |
| Requires: pos is valid<br> |
| Throws: nothing<br> |
| Returns: An object of type <tt>bitset<N>::reference</tt> such that <tt>(*this)[pos] |
| == this->test(pos)</tt>, and such that <tt>(*this)[pos] = val</tt> is equivalent to <tt>this->set(pos, |
| val);</tt></p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes Item 3 is not a defect. "Formatted |
| input" implies the desired semantics. See 27.6.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted"> [lib.istream.formatted]</a>. |
| </p> |
| <hr> |
| <a name="13"><h3>13. Eos refuses to die</h3></a><p><b>Section:</b> 27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> William M. Miller <b>Date:</b> 3 Mar 1998</p> |
| <p>In 27.6.1.2.3, there is a reference to "eos", which is |
| the only one in the whole draft (at least using Acrobat search), so |
| it's undefined. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a>, replace "eos" with |
| "charT()"</p> |
| <hr> |
| <a name="14"><h3>14. Locale::combine should be const</h3></a><p><b>Section:</b> 22.1.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.members"> [lib.locale.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>locale::combine is the only member function of locale (other than constructors and |
| destructor) that is not const. There is no reason for it not to be const, and good reasons |
| why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 |
| paragraph 6: "An instance of a locale is immutable." </p> |
| |
| <p>History: this member function originally was a constructor. it happened that the |
| interface it specified had no corresponding language syntax, so it was changed to a member |
| function. As constructors are never const, there was no "const" in the interface |
| which was transformed into member "combine". It should have been added at that |
| time, but the omission was not noticed. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> and also in 22.1.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.members"> [lib.locale.members]</a>, add |
| "const" to the declaration of member combine: </p> |
| <blockquote> |
| <pre>template <class Facet> locale combine(const locale& other) const; </pre> |
| </blockquote> |
| <hr> |
| <a name="15"><h3>15. Locale::name requirement inconsistent</h3></a><p><b>Section:</b> 22.1.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.members"> [lib.locale.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>locale::name() is described as returning a string that can be passed to a locale |
| constructor, but there is no matching constructor. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.members"> [lib.locale.members]</a>, paragraph 5, replace |
| "<tt>locale(name())</tt>" with |
| "<tt>locale(name().c_str())</tt>". |
| </p> |
| <hr> |
| <a name="16"><h3>16. Bad ctype_byname<char> decl</h3></a><p><b>Section:</b> 22.2.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.codecvt"> [lib.locale.codecvt]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The new virtual members ctype_byname<char>::do_widen and do_narrow did not get |
| edited in properly. Instead, the member do_widen appears four times, with wrong argument |
| lists. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>The correct declarations for the overloaded members |
| <tt>do_narrow</tt> and <tt>do_widen</tt> should be copied |
| from 22.2.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.ctype.special"> [lib.facet.ctype.special]</a>.</p> |
| <hr> |
| <a name="17"><h3>17. Bad bool parsing</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>This section describes the process of parsing a text boolean value from the input |
| stream. It does not say it recognizes either of the sequences "true" or |
| "false" and returns the corresponding bool value; instead, it says it recognizes |
| only one of those sequences, and chooses which according to the received value of a |
| reference argument intended for returning the result, and reports an error if the other |
| sequence is found. (!) Furthermore, it claims to get the names from the ctype<> |
| facet rather than the numpunct<> facet, and it examines the "boolalpha" |
| flag wrongly; it doesn't define the value "loc"; and finally, it computes |
| wrongly whether to use numeric or "alpha" parsing.<br> |
| <br> |
| I believe the correct algorithm is "as if": </p> |
| |
| <pre> // in, err, val, and str are arguments. |
| err = 0; |
| const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc()); |
| const string_type t = np.truename(), f = np.falsename(); |
| bool tm = true, fm = true; |
| size_t pos = 0; |
| while (tm && pos < t.size() || fm && pos < f.size()) { |
| if (in == end) { err = str.eofbit; } |
| bool matched = false; |
| if (tm && pos < t.size()) { |
| if (!err && t[pos] == *in) matched = true; |
| else tm = false; |
| } |
| if (fm && pos < f.size()) { |
| if (!err && f[pos] == *in) matched = true; |
| else fm = false; |
| } |
| if (matched) { ++in; ++pos; } |
| if (pos > t.size()) tm = false; |
| if (pos > f.size()) fm = false; |
| } |
| if (tm == fm || pos == 0) { err |= str.failbit; } |
| else { val = tm; } |
| return in;</pre> |
| |
| <p>Notice this works reasonably when the candidate strings are both empty, or equal, or |
| when one is a substring of the other. The proposed text below captures the logic of the |
| code above.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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>, in the first line of paragraph 14, |
| change "&&" to "&".</p> |
| |
| <p>Then, replace paragraphs 15 and 16 as follows:</p> |
| |
| <blockquote> |
| |
| <p>Otherwise target sequences are determined "as if" by |
| calling the members <tt>falsename()</tt> and |
| <tt>truename()</tt> of the facet obtained by |
| <tt>use_facet<numpunct<charT> >(str.getloc())</tt>. |
| Successive characters in the range <tt>[in,end)</tt> (see |
| [lib.sequence.reqmts]) are obtained and matched against |
| corresponding positions in the target sequences only as necessary to |
| identify a unique match. The input iterator <tt>in</tt> is |
| compared to <tt>end</tt> only when necessary to obtain a |
| character. If and only if a target sequence is uniquely matched, |
| <tt>val</tt> is set to the corresponding value.</p> |
| |
| </blockquote> |
| |
| <blockquote> |
| <p>The <tt>in</tt> iterator is always left pointing one position beyond the last character |
| successfully matched. If <tt>val</tt> is set, then err is set to <tt>str.goodbit</tt>; or to |
| <tt>str.eofbit</tt> if, when seeking another character to match, it is found that |
| <tt>(in==end)</tt>. If <tt>val</tt> is not set, then <i>err</i> is set to <tt>str.failbit</tt>; or to |
| <tt>(str.failbit|str.eofbit)</tt>if |
| the reason for the failure was that <tt>(in==end)</tt>. [Example: for targets |
| <tt>true</tt>:"a" and <tt>false</tt>:"abb", the input sequence "a" yields |
| <tt>val==true</tt> and <tt>err==str.eofbit</tt>; the input sequence "abc" yields |
| <tt>err=str.failbit</tt>, with <tt>in</tt> ending at the 'c' element. For targets |
| <tt>true</tt>:"1" |
| and <tt>false</tt>:"0", the input sequence "1" yields <tt>val==true</tt> |
| and <tt>err=str.goodbit</tt>. For empty targets (""), any input sequence yields |
| <tt>err==str.failbit</tt>. --end example]</p> |
| </blockquote> |
| <hr> |
| <a name="18"><h3>18. Get(...bool&) omitted</h3></a><p><b>Section:</b> 22.2.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.members"> [lib.facet.num.get.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In the list of num_get<> non-virtual members on page 22-23, the member |
| that parses bool values was omitted from the list of definitions of non-virtual |
| members, though it is listed in the class definition and the corresponding |
| virtual is listed everywhere appropriate. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add at the beginning of 22.2.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.members"> [lib.facet.num.get.members]</a> |
| another get member for bool&, copied from the entry in |
| 22.2.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.num.get"> [lib.locale.num.get]</a>.</p> |
| <hr> |
| <a name="19"><h3>19. "Noconv" definition too vague</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p> |
| In the definitions of codecvt<>::do_out and do_in, they are |
| specified to return noconv if "no conversion is |
| needed". This definition is too vague, and does not say |
| normatively what is done with the buffers. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the entry for noconv in the table under paragraph 4 in section |
| <font color="red">22.2.1.5.2</font> to read: |
| </p> |
| <blockquote> |
| <p><tt>noconv</tt>: <tt>internT</tt> and <tt>externT</tt> are the same type, |
| and input sequence is identical to converted sequence.</p> |
| </blockquote> |
| <p>Change the Note in paragraph 2 to normative text as follows:</p> |
| <blockquote> |
| <p>If returns <tt>noconv</tt>, <tt>internT</tt> and <tt>externT</tt> are the |
| same type and the converted sequence is identical to the input sequence <tt>[from,from_next)</tt>. |
| <tt>to_next</tt> is set equal to <tt>to</tt>, the value of <tt>state</tt> is |
| unchanged, and there are no changes to the values in <tt>[to, to_limit)</tt>.</p> |
| </blockquote> |
| <hr> |
| <a name="20"></a><h3><a name="20">20. Thousands_sep returns wrong type</a></h3><p><b>Section:</b> 22.2.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.numpunct.virtuals"> [lib.facet.numpunct.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The synopsis for numpunct<>::do_thousands_sep, and the |
| definition of numpunct<>::thousands_sep which calls it, specify |
| that it returns a value of type char_type. Here it is erroneously |
| described as returning a "string_type". </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.numpunct.virtuals"> [lib.facet.numpunct.virtuals]</a>, above paragraph 2, change |
| "string_type" to "char_type". </p> |
| <hr> |
| <a name="21"><h3>21. Codecvt_byname<> instantiations</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In the second table in the section, captioned "Required |
| instantiations", the instantiations for codecvt_byname<> |
| have been omitted. These are necessary to allow users to construct a |
| locale by name from facets. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add in 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> to the table captioned |
| "Required instantiations", in the category "ctype" |
| the lines </p> |
| |
| <blockquote> |
| <pre>codecvt_byname<char,char,mbstate_t>, |
| codecvt_byname<wchar_t,char,mbstate_t> </pre> |
| </blockquote> |
| <hr> |
| <a name="22"><h3>22. Member open vs. flags</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The description of basic_istream<>::open leaves unanswered questions about how it |
| responds to or changes flags in the error status for the stream. A strict reading |
| indicates that it ignores the bits and does not change them, which confuses users who do |
| not expect eofbit and failbit to remain set after a successful open. There are three |
| reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit |
| and eofbit on call to open(). </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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> paragraph 3, <i>and</i> in 27.8.1.10 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ofstream.members"> [lib.ofstream.members]</a> paragraph 3, under open() effects, add a footnote: |
| </p> |
| |
| <blockquote> |
| <p>A successful open does not change the error state.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>This may seem surprising to some users, but it's just an instance |
| of a general rule: error flags are never cleared by the |
| implementation. The only way error flags are are ever cleared is if |
| the user explicitly clears them by hand.</p> |
| |
| <p>The LWG believed that preserving this general rule was |
| important enough so that an exception shouldn't be made just for this |
| one case. The resolution of this issue clarifies what the LWG |
| believes to have been the original intent.</p> |
| |
| <hr> |
| <a name="24"><h3>24. "do_convert" doesn't exist</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The description of codecvt<>::do_out and do_in mentions a |
| symbol "do_convert" which is not defined in the |
| standard. This is a leftover from an edit, and should be "do_in |
| and do_out". </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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>, paragraph 3, change |
| "do_convert" to "do_in or do_out". Also, in <font color="red">22.2.1.5.2</font>, change "do_convert()" to "do_in |
| or do_out". </p> |
| <hr> |
| <a name="25"><h3>25. String operator<< uses width() value wrong</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In the description of operator<< applied to strings, the standard says that uses |
| the smaller of os.width() and str.size(), to pad "as described in stage 3" |
| elsewhere; but this is inconsistent, as this allows no possibility of space for padding. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 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> paragraph 4 from:<br> |
| <br> |
| "... where <tt>n</tt> is the smaller of <tt>os.width()</tt> and <tt>str.size()</tt>; |
| ..."<br> |
| <br> |
| to: <br> |
| <br> |
| "... where <tt>n</tt> is the larger of <tt>os.width()</tt> and <tt>str.size()</tt>; |
| ..."</p> |
| <hr> |
| <a name="26"><h3>26. Bad sentry example</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In paragraph 6, the code in the example: </p> |
| |
| <pre> template <class charT, class traits = char_traits<charT> > |
| basic_istream<charT,traits>::sentry( |
| basic_istream<charT,traits>& is, bool noskipws = false) { |
| ... |
| int_type c; |
| typedef ctype<charT> ctype_type; |
| const ctype_type& ctype = use_facet<ctype_type>(is.getloc()); |
| while ((c = is.rdbuf()->snextc()) != traits::eof()) { |
| if (ctype.is(ctype.space,c)==0) { |
| is.rdbuf()->sputbackc (c); |
| break; |
| } |
| } |
| ... |
| }</pre> |
| |
| <p>fails to demonstrate correct use of the facilities described. In |
| particular, it fails to use traits operators, and specifies incorrect |
| semantics. (E.g. it specifies skipping over the first character in the |
| sequence without examining it.) </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the example above from 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> |
| paragraph 6.</p> |
| <p><b>Rationale:</b></p> |
| <p>The originally proposed replacement code for the example was not |
| correct. The LWG tried in Kona and again in Tokyo to correct it |
| without success. In Tokyo, an implementor reported that actual working |
| code ran over one page in length and was quite complicated. The LWG |
| decided that it would be counter-productive to include such a lengthy |
| example, which might well still contain errors.</p> |
| <hr> |
| <a name="27"><h3>27. String::erase(range) yields wrong iterator</h3></a><p><b>Section:</b> 21.3.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::erase"> [lib.string::erase]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The string::erase(iterator first, iterator last) is specified to return an element one |
| place beyond the next element after the last one erased. E.g. for the string |
| "abcde", erasing the range ['b'..'d') would yield an iterator for element 'e', |
| while 'd' has not been erased. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 21.3.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::erase"> [lib.string::erase]</a>, paragraph 10, change: </p> |
| |
| <blockquote> |
| <p>Returns: an iterator which points to the element immediately following _last_ prior to |
| the element being erased. </p> |
| </blockquote> |
| |
| <p>to read </p> |
| |
| <blockquote> |
| <p>Returns: an iterator which points to the element pointed to by _last_ prior to the |
| other elements being erased. </p> |
| </blockquote> |
| <hr> |
| <a name="28"><h3>28. Ctype<char>is ambiguous</h3></a><p><b>Section:</b> 22.2.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.ctype.char.members"> [lib.facet.ctype.char.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The description of the vector form of ctype<char>::is can be interpreted to mean |
| something very different from what was intended. Paragraph 4 says </p> |
| |
| <blockquote> |
| <p>Effects: The second form, for all *p in the range [low, high), assigns vec[p-low] to |
| table()[(unsigned char)*p]. </p> |
| </blockquote> |
| |
| <p>This is intended to copy the value indexed from table()[] into the place identified in |
| vec[]. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 22.2.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.ctype.char.members"> [lib.facet.ctype.char.members]</a>, paragraph 4, to read </p> |
| |
| <blockquote> |
| <p>Effects: The second form, for all *p in the range [low, high), assigns into vec[p-low] |
| the value table()[(unsigned char)*p]. </p> |
| </blockquote> |
| <hr> |
| <a name="29"><h3>29. Ios_base::init doesn't exist</h3></a><p><b>Section:</b> 27.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.narrow.stream.objects"> [lib.narrow.stream.objects]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>Sections 27.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.narrow.stream.objects"> [lib.narrow.stream.objects]</a> and 27.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.wide.stream.objects"> [lib.wide.stream.objects]</a> mention |
| a function ios_base::init, which is not defined. Probably they mean |
| basic_ios<>::init, defined in 27.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.cons"> [lib.basic.ios.cons]</a>, |
| paragraph 3. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>[R12: modified to include paragraph 5.]</p> |
| |
| <p>In 27.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.narrow.stream.objects"> [lib.narrow.stream.objects]</a> paragraph 2 and 5, change </p> |
| |
| <blockquote> |
| <p>ios_base::init </p> |
| </blockquote> |
| |
| <p>to </p> |
| |
| <blockquote> |
| <p>basic_ios<char>::init </p> |
| </blockquote> |
| |
| <p>Also, make a similar change in 27.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.wide.stream.objects"> [lib.wide.stream.objects]</a> except it |
| should read </p> |
| |
| <blockquote> |
| <p>basic_ios<wchar_t>::init </p> |
| </blockquote> |
| <hr> |
| <a name="30"><h3>30. Wrong header for LC_*</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>Paragraph 2 implies that the C macros LC_CTYPE etc. are defined in <cctype>, |
| where they are in fact defined elsewhere to appear in <clocale>. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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>, paragraph 2, change |
| "<cctype>" to read "<clocale>". </p> |
| <hr> |
| <a name="31"><h3>31. Immutable locale values</h3></a><p><b>Section:</b> 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>Paragraph 6, says "An instance of <tt>locale</tt> is |
| <i>immutable</i>; once a facet reference is obtained from it, |
| ...". This has caused some confusion, because locale variables |
| are manifestly assignable. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> replace paragraph 6</p> |
| |
| <blockquote> |
| <p>An instance of <tt>locale</tt> is immutable; once a facet |
| reference is obtained from it, that reference remains usable as long |
| as the locale value itself exists.</p> |
| </blockquote> |
| |
| <p>with</p> |
| |
| <blockquote> |
| <p>Once a facet reference is obtained from a locale object by |
| calling use_facet<>, that reference remains usable, and the |
| results from member functions of it may be cached and re-used, as |
| long as some locale object refers to that facet.</p> |
| </blockquote> |
| <hr> |
| <a name="32"><h3>32. Pbackfail description inconsistent</h3></a><p><b>Section:</b> 27.5.2.4.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.pback"> [lib.streambuf.virt.pback]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The description of the required state before calling virtual member |
| basic_streambuf<>::pbackfail requirements is inconsistent with the conditions |
| described in 27.5.2.2.4 [lib.streambuf.pub.pback] where member sputbackc calls it. |
| Specifically, the latter says it calls pbackfail if: </p> |
| |
| <p> traits::eq(c,gptr()[-1]) is false </p> |
| |
| <p>where pbackfail claims to require: </p> |
| |
| <p> traits::eq(*gptr(),traits::to_char_type(c)) returns false </p> |
| |
| <p>It appears that the pbackfail description is wrong. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.5.2.4.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.pback"> [lib.streambuf.virt.pback]</a>, paragraph 1, change:</p> |
| |
| <blockquote> |
| <p>"<tt>traits::eq(*gptr(),traits::to_char_type( c))</tt>"</p> |
| </blockquote> |
| |
| <p>to </p> |
| |
| <blockquote> |
| <p>"<tt>traits::eq(traits::to_char_type(c),gptr()[-1])</tt>" |
| </p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Note deliberate reordering of arguments for clarity in addition to the correction of |
| the argument value.</p> |
| <hr> |
| <a name="33"><h3>33. Codecvt<> mentions from_type</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In the table defining the results from do_out and do_in, the specification for the |
| result <i>error</i> says </p> |
| |
| <blockquote> |
| <p>encountered a from_type character it could not convert </p> |
| </blockquote> |
| |
| <p>but from_type is not defined. This clearly is intended to be an externT for do_in, or |
| an internT for do_out. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In <font color="red">22.2.1.5.2</font> paragraph 4, replace the definition |
| in the table for the case of _error_ with </p> |
| |
| <blockquote> |
| <p>encountered a character in <tt>[from,from_end)</tt> that it could not convert. </p> |
| </blockquote> |
| <hr> |
| <a name="34"><h3>34. True/falsename() not in ctype<></h3></a><p><b>Section:</b> 22.2.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In paragraph 19, Effects:, members truename() and falsename are used from facet |
| ctype<charT>, but it has no such members. Note that this is also a problem in |
| 22.2.2.1.2, addressed in (4). </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a>, paragraph 19, in the Effects: |
| clause for member put(...., bool), replace the initialization of the |
| string_type value s as follows: </p> |
| |
| <blockquote> |
| <pre>const numpunct& np = use_facet<numpunct<charT> >(loc); |
| string_type s = val ? np.truename() : np.falsename(); </pre> |
| </blockquote> |
| <hr> |
| <a name="35"><h3>35. No manipulator unitbuf in synopsis</h3></a><p><b>Section:</b> 27.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostreams.base"> [lib.iostreams.base]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In 27.4.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fmtflags.manip"> [lib.fmtflags.manip]</a>, we have a definition for a manipulator |
| named "unitbuf". Unlike other manipulators, it's not listed |
| in synopsis. Similarly for "nounitbuf". </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to the synopsis for <ios> in 27.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostreams.base"> [lib.iostreams.base]</a>, after |
| the entry for "nouppercase", the prototypes: </p> |
| |
| <blockquote> |
| <pre>ios_base& unitbuf(ios_base& str); |
| ios_base& nounitbuf(ios_base& str); </pre> |
| </blockquote> |
| <hr> |
| <a name="36"><h3>36. Iword & pword storage lifetime omitted</h3></a><p><b>Section:</b> 27.4.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.storage"> [lib.ios.base.storage]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In the definitions for ios_base::iword and pword, the lifetime of the storage is |
| specified badly, so that an implementation which only keeps the last value stored appears |
| to conform. In particular, it says: </p> |
| |
| <p>The reference returned may become invalid after another call to the object's iword |
| member with a different index ... </p> |
| |
| <p>This is not idle speculation; at least one implementation was done this way. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add in 27.4.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.storage"> [lib.ios.base.storage]</a>, in both paragraph 2 and also in |
| paragraph 4, replace the sentence: </p> |
| |
| <blockquote> |
| <p>The reference returned may become invalid after another call to the object's iword |
| [pword] member with a different index, after a call to its copyfmt member, or when the |
| object is destroyed. </p> |
| </blockquote> |
| |
| <p>with: </p> |
| |
| <blockquote> |
| <p>The reference returned is invalid after any other operations on the object. However, |
| the value of the storage referred to is retained, so that until the next call to copyfmt, |
| calling iword [pword] with the same index yields another reference to the same value. </p> |
| </blockquote> |
| |
| <p>substituting "iword" or "pword" as appropriate. </p> |
| <hr> |
| <a name="37"><h3>37. Leftover "global" reference</h3></a><p><b>Section:</b> 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>In the overview of locale semantics, paragraph 4, is the sentence </p> |
| |
| <blockquote> |
| <p>If Facet is not present in a locale (or, failing that, in the global locale), it throws |
| the standard exception bad_cast. </p> |
| </blockquote> |
| |
| <p>This is not supported by the definition of use_facet<>, and represents semantics |
| from an old draft. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a>, paragraph 4, delete the parenthesized |
| expression </p> |
| |
| <blockquote> |
| <p>(or, failing that, in the global locale) </p> |
| </blockquote> |
| <hr> |
| <a name="38"><h3>38. Facet definition incomplete</h3></a><p><b>Section:</b> 22.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.global.templates"> [lib.locale.global.templates]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>It has been noticed by Esa Pulkkinen that the definition of |
| "facet" is incomplete. In particular, a class derived from |
| another facet, but which does not define a member <i>id</i>, cannot |
| safely serve as the argument <i>F</i> to use_facet<F>(loc), |
| because there is no guarantee that a reference to the facet instance |
| stored in <i>loc</i> is safely convertible to <i>F</i>. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In the definition of std::use_facet<>(), replace the text in paragraph 1 which |
| reads: </p> |
| |
| <blockquote> |
| <p>Get a reference to a facet of a locale. </p> |
| </blockquote> |
| |
| <p>with: </p> |
| |
| <blockquote> |
| <p>Requires: <tt>Facet</tt> is a facet class whose definition |
| contains the public static member <tt>id</tt> as defined in 22.1.1.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.facet"> [lib.locale.facet]</a>. </p> |
| </blockquote> |
| |
| <p><i>[ |
| Kona: strike as overspecification the text "(not inherits)" |
| from the original resolution, which read "... whose definition |
| contains (not inherits) the public static member |
| <tt>id</tt>..." |
| ]</i></p> |
| |
| <hr> |
| <a name="39"><h3>39. istreambuf_iterator<>::operator++(int) definition garbled</h3></a><p><b>Section:</b> 24.5.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator::op++"> [lib.istreambuf.iterator::op++]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>Following the definition of istreambuf_iterator<>::operator++(int) in paragraph |
| 3, the standard contains three lines of garbage text left over from a previous edit. </p> |
| |
| <blockquote> |
| <pre>istreambuf_iterator<charT,traits> tmp = *this; |
| sbuf_->sbumpc(); |
| return(tmp); </pre> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.5.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator::op++"> [lib.istreambuf.iterator::op++]</a>, delete the three lines of code at the |
| end of paragraph 3. </p> |
| <hr> |
| <a name="40"><h3>40. Meaningless normative paragraph in examples</h3></a><p><b>Section:</b> 22.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facets.examples"> [lib.facets.examples]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>Paragraph 3 of the locale examples is a description of part of an |
| implementation technique that has lost its referent, and doesn't mean |
| anything. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Delete 22.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facets.examples"> [lib.facets.examples]</a> paragraph 3 which begins "This |
| initialization/identification system depends...", or (at the |
| editor's option) replace it with a place-holder to keep the paragraph |
| numbering the same. </p> |
| <hr> |
| <a name="41"><h3>41. Ios_base needs clear(), exceptions()</h3></a><p><b>Section:</b> 27.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base"> [lib.ios.base]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The description of ios_base::iword() and pword() in 27.4.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.members.static"> [lib.ios.members.static]</a>, say that if they fail, they "set badbit, |
| which may throw an exception". However, ios_base offers no |
| interface to set or to test badbit; those interfaces are defined in |
| basic_ios<>. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the description in 27.4.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.storage"> [lib.ios.base.storage]</a> in |
| paragraph 2, and also in paragraph 4, as follows. Replace</p> |
| |
| <blockquote> |
| <p>If the function fails it sets badbit, which may throw an exception.</p> |
| </blockquote> |
| |
| <p>with</p> |
| |
| <blockquote> |
| <p>If the function fails, and <tt>*this</tt> is a base sub-object of |
| a <tt>basic_ios<></tt> object or sub-object, the effect is |
| equivalent to calling <tt>basic_ios<>::setstate(badbit)</tt> |
| on the derived object (which may throw <tt>failure</tt>).</p> |
| </blockquote> |
| |
| <p><i>[Kona: LWG reviewed wording; setstate(failbit) changed to |
| setstate(badbit).]</i></p> |
| |
| <hr> |
| <a name="42"><h3>42. String ctors specify wrong default allocator</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#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>The basic_string<> copy constructor: </p> |
| |
| <pre>basic_string(const basic_string& str, size_type pos = 0, |
| size_type n = npos, const Allocator& a = Allocator()); </pre> |
| |
| <p>specifies an Allocator argument default value that is |
| counter-intuitive. The natural choice for a the allocator to copy from |
| is str.get_allocator(). Though this cannot be expressed in |
| default-argument notation, overloading suffices. </p> |
| |
| <p>Alternatively, the other containers in Clause 23 (deque, list, |
| vector) do not have this form of constructor, so it is inconsistent, |
| and an evident source of confusion, for basic_string<> to have |
| it, so it might better be removed. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> In 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a>, replace the declaration of the copy |
| constructor as follows: </p> |
| |
| <blockquote> |
| <pre>basic_string(const basic_string& str); |
| basic_string(const basic_string& str, size_type pos, size_type n = npos, |
| const Allocator& a = Allocator());</pre> |
| </blockquote> |
| |
| <p>In 21.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.cons"> [lib.string.cons]</a>, replace the copy constructor declaration |
| as above. Add to paragraph 5, Effects:</p> |
| |
| <blockquote> |
| <p>In the first form, the Allocator value used is copied from |
| <tt>str.get_allocator()</tt>.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes the constructor is actually broken, rather than |
| just an unfortunate design choice.</p> |
| |
| <p>The LWG considered two other possible resolutions:</p> |
| |
| <p>A. In 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a>, replace the declaration of the copy |
| constructor as follows:</p> |
| |
| <blockquote> |
| <pre>basic_string(const basic_string& str, size_type pos = 0, |
| size_type n = npos); |
| basic_string(const basic_string& str, size_type pos, |
| size_type n, const Allocator& a); </pre> |
| </blockquote> |
| |
| <p>In 21.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.cons"> [lib.string.cons]</a>, replace the copy constructor declaration |
| as above. Add to paragraph 5, Effects: </p> |
| |
| <blockquote> |
| <p>When no <tt>Allocator</tt> argument is provided, the string is constructed using the |
| value <tt>str.get_allocator()</tt>. </p> |
| </blockquote> |
| |
| <p>B. In 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a>, and also in 21.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.cons"> [lib.string.cons]</a>, replace |
| the declaration of the copy constructor as follows: </p> |
| |
| <blockquote> |
| <pre>basic_string(const basic_string& str, size_type pos = 0, |
| size_type n = npos); </pre> |
| </blockquote> |
| |
| <p>The proposed resolution reflects the original intent of the LWG. It |
| was also noted by Pete Becker that this fix "will cause |
| a small amount of existing code to now work correctly."</p> |
| |
| <p><i>[ |
| Kona: issue editing snafu fixed - the proposed resolution now correctly |
| reflects the LWG consensus. |
| ]</i></p> |
| <hr> |
| <a name="44"><h3>44. Iostreams use operator== on int_type values</h3></a><p><b>Section:</b> 27 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p> |
| <p>Many of the specifications for iostreams specify that character |
| values or their int_type equivalents are compared using operators == |
| or !=, though in other places traits::eq() or traits::eq_int_type is |
| specified to be used throughout. This is an inconsistency; we should |
| change uses of == and != to use the traits members instead. </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Pre-Kona: Dietmar supplied wording]</i></p> |
| |
| <p>List of changes to clause 27:</p> |
| <ol> |
| <li> |
| In lib.basic.ios.members paragraph 13 (postcondition clause for |
| 'fill(cT)') change |
| |
| <blockquote> |
| fillch == fill() |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(fillch, fill()) |
| </blockquote> |
| |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 7 (effects clause for |
| 'get(cT,streamsize,cT)'), third bullet, change |
| |
| <blockquote> |
| c == delim for the next available input character c |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(c, delim) for the next available input character c |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 12 (effects clause for |
| 'get(basic_streambuf<cT,Tr>&,cT)'), third bullet, change |
| |
| <blockquote> |
| c == delim for the next available input character c |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(c, delim) for the next available input character c |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 17 (effects clause for |
| 'getline(cT,streamsize,cT)'), second bullet, change |
| |
| <blockquote> |
| c == delim for the next available input character c |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(c, delim) for the next available input character c |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 24 (effects clause for |
| 'ignore(int,int_type)'), second bullet, change |
| |
| <blockquote> |
| c == delim for the next available input character c |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq_int_type(c, delim) for the next available input |
| character c |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 25 (notes clause for |
| 'ignore(int,int_type)'), second bullet, change |
| |
| <blockquote> |
| The last condition will never occur if delim == traits::eof() |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| The last condition will never occur if |
| traits::eq_int_type(delim, traits::eof()). |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.sentry paragraph 6 (example implementation for the |
| sentry constructor) change |
| |
| <blockquote> |
| while ((c = is.rdbuf()->snextc()) != traits::eof()) { |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| while (!traits::eq_int_type(c = is.rdbuf()->snextc(), traits::eof())) { |
| </blockquote> |
| |
| </li> |
| </ol> |
| |
| <p>List of changes to Chapter 21:</p> |
| |
| <ol> |
| <li> |
| In lib.string::find paragraph 1 (effects clause for find()), |
| second bullet, change |
| |
| <blockquote> |
| at(xpos+I) == str.at(I) for all elements ... |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.string::rfind paragraph 1 (effects clause for rfind()), |
| second bullet, change |
| |
| <blockquote> |
| at(xpos+I) == str.at(I) for all elements ... |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.string::find.first.of paragraph 1 (effects clause for |
| find_first_of()), second bullet, change |
| |
| <blockquote> |
| at(xpos+I) == str.at(I) for all elements ... |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.string::find.last.of paragraph 1 (effects clause for |
| find_last_of()), second bullet, change |
| |
| <blockquote> |
| at(xpos+I) == str.at(I) for all elements ... |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </blockquote> |
| |
| </li> |
| <li> |
| In lib.string::find.first.not.of paragraph 1 (effects clause for |
| find_first_not_of()), second bullet, change |
| |
| <blockquote> |
| at(xpos+I) == str.at(I) for all elements ... |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </blockquote> |
| </li> |
| |
| <li> |
| In lib.string::find.last.not.of paragraph 1 (effects clause for |
| find_last_not_of()), second bullet, change |
| |
| <blockquote> |
| at(xpos+I) == str.at(I) for all elements ... |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </blockquote> |
| </li> |
| |
| <li> |
| In lib.string.ios paragraph 5 (effects clause for getline()), |
| second bullet, change |
| |
| <blockquote> |
| c == delim for the next available input character c |
| </blockquote> |
| |
| to |
| |
| <blockquote> |
| traits::eq(c, delim) for the next available input character c |
| </blockquote> |
| </li> |
| |
| </ol> |
| |
| <p>Notes:</p> |
| <ul> |
| <li> |
| Fixing this issue highlights another sloppyness in |
| lib.istream.unformatted paragraph 24: this clause mentions a "character" |
| which is then compared to an 'int_type' (see item 5. in the list |
| below). It is not clear whether this requires explicit words and |
| if so what these words are supposed to be. A similar issue exists, |
| BTW, for operator*() of istreambuf_iterator which returns the result |
| of sgetc() as a character type (see lib.istreambuf.iterator::op* |
| paragraph 1), and for operator++() of istreambuf_iterator which |
| passes the result of sbumpc() to a constructor taking a char_type |
| (see lib.istreambuf.iterator::operator++ paragraph 3). Similarily, the |
| assignment operator ostreambuf_iterator passes a char_type to a function |
| taking an int_type (see lib.ostreambuf.iter.ops paragraph 1). |
| </li> |
| <li> |
| It is inconsistent to use comparisons using the traits functions in |
| Chapter 27 while not using them in Chapter 21, especially as some |
| of the inconsistent uses actually involve streams (eg. getline() on |
| streams). To avoid leaving this issue open still longer due to this |
| inconsistency (it is open since 1998), a list of changes to Chapter |
| 21 is below. |
| </li> |
| <li> |
| In Chapter 24 there are several places with statements like "the end |
| of stream is reached (streambuf_type::sgetc() returns traits::eof())" |
| (lib.istreambuf.iterator paragraph 1, lib.ostreambuf.iter.ops |
| paragraph 5). It is unclear whether these should be clarified to use |
| traits::eq_int_type() for detecting traits::eof(). |
| </li> |
| </ul> |
| |
| <hr> |
| <a name="46"><h3>46. Minor Annex D errors</h3></a><p><b>Section:</b> D.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.str.strstreams"> [depr.str.strstreams]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Brendan Kehoe <b>Date:</b> 1 Jun 1998</p> |
| <p>See lib-6522 and edit-814.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change D.7.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstreambuf"> [depr.strstreambuf]</a> (since streambuf is a typedef of |
| basic_streambuf<char>) from:</p> |
| |
| <pre> virtual streambuf<char>* setbuf(char* s, streamsize n);</pre> |
| |
| <p>to:</p> |
| |
| <pre> virtual streambuf* setbuf(char* s, streamsize n);</pre> |
| |
| <p>In D.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstream"> [depr.strstream]</a> insert the semicolon now missing after |
| int_type:</p> |
| |
| <pre> namespace std { |
| class strstream |
| : public basic_iostream<char> { |
| public: |
| // Types |
| typedef char char_type; |
| typedef typename char_traits<char>::int_type int_type |
| typedef typename char_traits<char>::pos_type pos_type;</pre> |
| <hr> |
| <a name="47"><h3>47. Imbue() and getloc() Returns clauses swapped</h3></a><p><b>Section:</b> 27.4.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.locales"> [lib.ios.base.locales]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 21 Jun 1998</p> |
| <p>Section 27.4.2.3 specifies how imbue() and getloc() work. That |
| section has two RETURNS clauses, and they make no sense as |
| stated. They make perfect sense, though, if you swap them. Am I |
| correct in thinking that paragraphs 2 and 4 just got mixed up by |
| accident?</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.4.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.locales"> [lib.ios.base.locales]</a> swap paragraphs 2 and 4.</p> |
| <hr> |
| <a name="48"><h3>48. Use of non-existent exception constructor</h3></a><p><b>Section:</b> 27.4.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios::failure"> [lib.ios::failure]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 21 Jun 1998</p> |
| <p>27.4.2.1.1, paragraph 2, says that class failure initializes the |
| base class, exception, with exception(msg). Class exception (see |
| 18.6.1) has no such constructor.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 27.4.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios::failure"> [lib.ios::failure]</a>, paragraph 2, with</p> |
| |
| <blockquote> |
| <p>EFFECTS: Constructs an object of class <tt>failure</tt>.</p> |
| </blockquote> |
| <hr> |
| <a name="49"><h3>49. Underspecification of ios_base::sync_with_stdio</h3></a><p><b>Section:</b> 27.4.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.members.static"> [lib.ios.members.static]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 21 Jun 1998</p> |
| <p>Two problems</p> |
| |
| <p>(1) 27.4.2.4 doesn't say what ios_base::sync_with_stdio(f) |
| returns. Does it return f, or does it return the previous |
| synchronization state? My guess is the latter, but the standard |
| doesn't say so.</p> |
| |
| <p>(2) 27.4.2.4 doesn't say what it means for streams to be |
| synchronized with stdio. Again, of course, I can make some |
| guesses. (And I'm unhappy about the performance implications of those |
| guesses, but that's another matter.)</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the following sentence in 27.4.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.members.static"> [lib.ios.members.static]</a> |
| returns clause from:</p> |
| |
| <blockquote> |
| <p><tt>true</tt> if the standard iostream objects (27.3) are |
| synchronized and otherwise returns <tt>false</tt>.</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p><tt>true</tt> if the previous state of the standard iostream |
| objects (27.3) was synchronized and otherwise returns |
| <tt>false</tt>.</p> |
| </blockquote> |
| |
| <p>Add the following immediately after 27.4.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.members.static"> [lib.ios.members.static]</a>, |
| paragraph 2:</p> |
| |
| <blockquote> |
| <p>When a standard iostream object str is <i>synchronized</i> with a |
| standard stdio stream f, the effect of inserting a character c by</p> |
| <pre> fputc(f, c); |
| </pre> |
| |
| <p>is the same as the effect of</p> |
| <pre> str.rdbuf()->sputc(c); |
| </pre> |
| |
| <p>for any sequence of characters; the effect of extracting a |
| character c by</p> |
| <pre> c = fgetc(f); |
| </pre> |
| |
| <p>is the same as the effect of:</p> |
| <pre> c = str.rdbuf()->sbumpc(c); |
| </pre> |
| |
| <p>for any sequences of characters; and the effect of pushing |
| back a character c by</p> |
| <pre> ungetc(c, f); |
| </pre> |
| |
| <p>is the same as the effect of</p> |
| <pre> str.rdbuf()->sputbackc(c); |
| </pre> |
| |
| <p>for any sequence of characters. [<i>Footnote</i>: This implies |
| that operations on a standard iostream object can be mixed arbitrarily |
| with operations on the corresponding stdio stream. In practical |
| terms, synchronization usually means that a standard iostream object |
| and a standard stdio object share a buffer. <i>--End Footnote</i>]</p> |
| </blockquote> |
| |
| <p><i>[pre-Copenhagen: PJP and Matt contributed the definition |
| of "synchronization"]</i></p> |
| |
| <p><i>[post-Copenhagen: proposed resolution was revised slightly: |
| text was added in the non-normative footnote to say that operations |
| on the two streams can be mixed arbitrarily.]</i></p> |
| <hr> |
| <a name="50"><h3>50. Copy constructor and assignment operator of ios_base</h3></a><p><b>Section:</b> 27.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base"> [lib.ios.base]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 21 Jun 1998</p> |
| <p>As written, ios_base has a copy constructor and an assignment |
| operator. (Nothing in the standard says it doesn't have one, and all |
| classes have copy constructors and assignment operators unless you |
| take specific steps to avoid them.) However, nothing in 27.4.2 says |
| what the copy constructor and assignment operator do. </p> |
| |
| <p>My guess is that this was an oversight, that ios_base is, like |
| basic_ios, not supposed to have a copy constructor or an assignment |
| operator.</p> |
| |
| <p> |
| Jerry Schwarz comments: Yes, its an oversight, but in the opposite |
| sense to what you're suggesting. At one point there was a definite |
| intention that you could copy ios_base. It's an easy way to save the |
| entire state of a stream for future use. As you note, to carry out |
| that intention would have required a explicit description of the |
| semantics (e.g. what happens to the iarray and parray stuff). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base"> [lib.ios.base]</a>, class ios_base, specify the copy |
| constructor and operator= members as being private.</p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes the difficulty of specifying correct semantics |
| outweighs any benefit of allowing ios_base objects to be copyable.</p> |
| <hr> |
| <a name="51"><h3>51. Requirement to not invalidate iterators missing</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#TC">TC</a> <b>Submitter:</b> David Vandevoorde <b>Date:</b> 23 Jun 1998</p> |
| <p>The std::sort algorithm can in general only sort a given sequence |
| by moving around values. The list<>::sort() member on the other |
| hand could move around values or just update internal pointers. Either |
| method can leave iterators into the list<> dereferencable, but |
| they would point to different things. </p> |
| |
| <p>Does the FDIS mandate anywhere which method should be used for |
| list<>::sort()?</p> |
| |
| <p>Matt Austern comments:</p> |
| |
| <p>I think you've found an omission in the standard. </p> |
| |
| <p>The library working group discussed this point, and there was |
| supposed to be a general requirement saying that list, set, map, |
| multiset, and multimap may not invalidate iterators, or change the |
| values that iterators point to, except when an operation does it |
| explicitly. So, for example, insert() doesn't invalidate any iterators |
| and erase() and remove() only invalidate iterators pointing to the |
| elements that are being erased. </p> |
| |
| <p>I looked for that general requirement in the FDIS, and, while I |
| found a limited form of it for the sorted associative containers, I |
| didn't find it for list. It looks like it just got omitted. </p> |
| |
| <p>The intention, though, is that list<>::sort does not |
| invalidate any iterators and does not change the values that any |
| iterator points to. There would be no reason to have the member |
| function otherwise.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a new paragraph at the end of 23.1:</p> |
| |
| <blockquote> |
| <p>Unless otherwise specified (either explicitly or by defining a function in terms of |
| other functions), invoking a container member function or passing a container as an |
| argument to a library function shall not invalidate iterators to, or change the values of, |
| objects within that container. </p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>This was US issue CD2-23-011; it was accepted in London but the |
| change was not made due to an editing oversight. The wording in the |
| proposed resolution below is somewhat updated from CD2-23-011, |
| particularly the addition of the phrase "or change the values |
| of"</p> |
| <hr> |
| <a name="52"><h3>52. Small I/O problems</h3></a><p><b>Section:</b> 27.4.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fpos.operations"> [lib.fpos.operations]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 23 Jun 1998</p> |
| <p>First, 27.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.cons"> [lib.basic.ios.cons]</a>, table 89. This is pretty obvious: |
| it should be titled "basic_ios<>() effects", not |
| "ios_base() effects". </p> |
| |
| <p>[The second item is a duplicate; see issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#6">6</a> for |
| resolution.]</p> |
| |
| <p>Second, 27.4.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fpos.operations"> [lib.fpos.operations]</a> table 88 . There are a couple |
| different things wrong with it, some of which I've already discussed |
| with Jerry, but the most obvious mechanical sort of error is that it |
| uses expressions like P(i) and p(i), without ever defining what sort |
| of thing "i" is. |
| </p> |
| |
| <p>(The other problem is that it requires support for streampos |
| arithmetic. This is impossible on some systems, i.e. ones where file |
| position is a complicated structure rather than just a number. Jerry |
| tells me that the intention was to require syntactic support for |
| streampos arithmetic, but that it wasn't actually supposed to do |
| anything meaningful except on platforms, like Unix, where genuine |
| arithmetic is possible.) </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.cons"> [lib.basic.ios.cons]</a> table 89 title from |
| "ios_base() effects" to "basic_ios<>() |
| effects". </p> |
| <hr> |
| <a name="53"><h3>53. Basic_ios destructor unspecified</h3></a><p><b>Section:</b> 27.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.cons"> [lib.basic.ios.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 23 Jun 1998</p> |
| <p>There's nothing in 27.4.4 saying what basic_ios's destructor does. |
| The important question is whether basic_ios::~basic_ios() destroys |
| rdbuf().</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add after 27.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.cons"> [lib.basic.ios.cons]</a> paragraph 2:</p> |
| |
| <blockquote> |
| <p><tt>virtual ~basic_ios();</tt></p> |
| <p><b>Notes</b>: The destructor does not destroy <tt>rdbuf()</tt>.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The LWG reviewed the additional question of whether or not |
| <tt>rdbuf(0)</tt> may set <tt>badbit</tt>. The answer is |
| clearly yes; it may be set via <tt>clear()</tt>. See 27.4.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.members"> [lib.basic.ios.members]</a>, paragraph 6. This issue was reviewed at length |
| by the LWG, which removed from the original proposed resolution a |
| footnote which incorrectly said "<tt>rdbuf(0)</tt> does not set |
| <tt>badbit</tt>".</p> |
| <hr> |
| <a name="54"><h3>54. Basic_streambuf's destructor</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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 25 Jun 1998</p> |
| <p>The class synopsis for basic_streambuf shows a (virtual) |
| destructor, but the standard doesn't say what that destructor does. My |
| assumption is that it does nothing, but the standard should say so |
| explicitly. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add after 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> paragraph 2:</p> |
| |
| <blockquote> |
| <p><tt>virtual ~basic_streambuf();</tt></p> |
| <p><b>Effects</b>: None.</p> |
| </blockquote> |
| <hr> |
| <a name="55"><h3>55. Invalid stream position is undefined</h3></a><p><b>Section:</b> 27 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 26 Jun 1998</p> |
| <p>Several member functions in clause 27 are defined in certain |
| circumstances to return an "invalid stream position", a term |
| that is defined nowhere in the standard. Two places (27.5.2.4.2, |
| paragraph 4, and 27.8.1.4, paragraph 15) contain a cross-reference to |
| a definition in _lib.iostreams.definitions_, a nonexistent |
| section. </p> |
| |
| <p>I suspect that the invalid stream position is just supposed to be |
| pos_type(-1). Probably best to say explicitly in (for example) |
| 27.5.2.4.2 that the return value is pos_type(-1), rather than to use |
| the term "invalid stream position", define that term |
| somewhere, and then put in a cross-reference. </p> |
| |
| <p>The phrase "invalid stream position" appears ten times in |
| the C++ Standard. In seven places it refers to a return value, and it |
| should be changed. In three places it refers to an argument, and it |
| should not be changed. Here are the three places where "invalid |
| stream position" should not be changed:</p> |
| |
| <blockquote> |
| <p>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>, paragraph 14<br> |
| 27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a>, paragraph 14<br> |
| D.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstreambuf.virtuals"> [depr.strstreambuf.virtuals]</a>, paragraph 17 |
| </p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.5.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a>, paragraph 4, change "Returns an |
| object of class pos_type that stores an invalid stream position |
| (_lib.iostreams.definitions_)" to "Returns |
| <tt>pos_type(off_type(-1))</tt>". |
| </p> |
| |
| <p>In 27.5.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a>, paragraph 6, change "Returns |
| an object of class pos_type that stores an invalid stream |
| position" to "Returns <tt>pos_type(off_type(-1))</tt>".</p> |
| |
| <p>In 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>, paragraph 13, change "the object |
| stores an invalid stream position" to "the return value is |
| <tt>pos_type(off_type(-1))</tt>". </p> |
| |
| <p>In 27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a>, paragraph 13, change "returns an |
| invalid stream position (27.4.3)" to "returns |
| <tt>pos_type(off_type(-1))</tt>" </p> |
| |
| <p>In 27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a>, paragraph 15, change "Otherwise |
| returns an invalid stream position (_lib.iostreams.definitions_)" |
| to "Otherwise returns <tt>pos_type(off_type(-1))</tt>" |
| </p> |
| |
| <p>In D.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstreambuf.virtuals"> [depr.strstreambuf.virtuals]</a>, paragraph 15, change "the object |
| stores an invalid stream position" to "the return value is |
| <tt>pos_type(off_type(-1))</tt>" </p> |
| |
| <p>In D.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstreambuf.virtuals"> [depr.strstreambuf.virtuals]</a>, paragraph 18, change "the object |
| stores an invalid stream position" to "the return value is |
| <tt>pos_type(off_type(-1))</tt>"</p> |
| <hr> |
| <a name="56"><h3>56. Showmanyc's return type</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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 29 Jun 1998</p> |
| <p>The class summary for basic_streambuf<>, in 27.5.2, says that |
| showmanyc has return type int. However, 27.5.2.4.3 says that its |
| return type is streamsize. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change <tt>showmanyc</tt>'s return type in the |
| 27.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf"> [lib.streambuf]</a> class summary to <tt>streamsize</tt>.</p> |
| <hr> |
| <a name="57"><h3>57. Mistake in char_traits</h3></a><p><b>Section:</b> 21.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits.specializations.wchar.t"> [lib.char.traits.specializations.wchar.t]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 1 Jul 1998</p> |
| <p>21.1.3.2, paragraph 3, says "The types streampos and |
| wstreampos may be different if the implementation supports no shift |
| encoding in narrow-oriented iostreams but supports one or more shift |
| encodings in wide-oriented streams". </p> |
| |
| <p>That's wrong: the two are the same type. The <iosfwd> summary |
| in 27.2 says that streampos and wstreampos are, respectively, synonyms |
| for fpos<char_traits<char>::state_type> and |
| fpos<char_traits<wchar_t>::state_type>, and, flipping back |
| to clause 21, we see in 21.1.3.1 and 21.1.3.2 that |
| char_traits<char>::state_type and |
| char_traits<wchar_t>::state_type must both be mbstate_t. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the sentence in 21.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits.specializations.wchar.t"> [lib.char.traits.specializations.wchar.t]</a> paragraph 3 which |
| begins "The types streampos and wstreampos may be |
| different..." . </p> |
| <hr> |
| <a name="59"><h3>59. Ambiguity in specification of gbump</h3></a><p><b>Section:</b> 27.5.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.get.area"> [lib.streambuf.get.area]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 28 Jul 1998</p> |
| <p>27.5.2.3.1 says that basic_streambuf::gbump() "Advances the |
| next pointer for the input sequence by n." </p> |
| |
| <p>The straightforward interpretation is that it is just gptr() += |
| n. An alternative interpretation, though, is that it behaves as if it |
| calls sbumpc n times. (The issue, of course, is whether it might ever |
| call underflow.) There is a similar ambiguity in the case of |
| pbump. </p> |
| |
| <p>(The "classic" AT&T implementation used the |
| former interpretation.)</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.5.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.get.area"> [lib.streambuf.get.area]</a> paragraph 4 gbump effects from:</p> |
| |
| <blockquote> |
| <p>Effects: Advances the next pointer for the input sequence by n.</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Effects: Adds <tt>n</tt> to the next pointer for the input sequence.</p> |
| </blockquote> |
| |
| <p>Make the same change to 27.5.2.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.put.area"> [lib.streambuf.put.area]</a> paragraph 4 pbump |
| effects.</p> |
| <hr> |
| <a name="60"><h3>60. What is a formatted input function?</h3></a><p><b>Section:</b> 27.6.1.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.reqmts"> [lib.istream.formatted.reqmts]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 3 Aug 1998</p> |
| <p>Paragraph 1 of 27.6.1.2.1 contains general requirements for all |
| formatted input functions. Some of the functions defined in section |
| 27.6.1.2 explicitly say that those requirements apply ("Behaves |
| like a formatted input member (as described in 27.6.1.2.1)"), but |
| others don't. The question: is 27.6.1.2.1 supposed to apply to |
| everything in 27.6.1.2, or only to those member functions that |
| explicitly say "behaves like a formatted input member"? Or |
| to put it differently: are we to assume that everything that appears |
| in a section called "Formatted input functions" really is a |
| formatted input function? I assume that 27.6.1.2.1 is intended to |
| apply to the arithmetic extractors (27.6.1.2.2), but I assume that it |
| is not intended to apply to extractors like </p> |
| |
| <pre> basic_istream& operator>>(basic_istream& (*pf)(basic_istream&));</pre> |
| |
| <p>and </p> |
| |
| <pre> basic_istream& operator>>(basic_streammbuf*);</pre> |
| |
| <p>There is a similar ambiguity for unformatted input, formatted output, and unformatted |
| output. </p> |
| |
| <p>Comments from Judy Ward: It seems like the problem is that the |
| basic_istream and basic_ostream operator <<()'s that are used |
| for the manipulators and streambuf* are in the wrong section and |
| should have their own separate section or be modified to make it clear |
| that the "Common requirements" listed in section 27.6.1.2.1 |
| (for basic_istream) and section 27.6.2.5.1 (for basic_ostream) do not |
| apply to them. </p> |
| |
| <p>Additional comments from Dietmar Kühl: It appears to be somewhat |
| nonsensical to consider the functions defined in 27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a> paragraphs 1 to 5 to be "Formatted input |
| function" but since these functions are defined in a section |
| labeled "Formatted input functions" it is unclear to me |
| whether these operators are considered formatted input functions which |
| have to conform to the "common requirements" from 27.6.1.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.reqmts"> [lib.istream.formatted.reqmts]</a>: If this is the case, all manipulators, not |
| just <tt>ws</tt>, would skip whitespace unless <tt>noskipws</tt> is |
| set (... but setting <tt>noskipws</tt> using the manipulator syntax |
| would also skip whitespace :-)</p> <p>It is not clear which functions |
| are to be considered unformatted input functions. As written, it seems |
| that all functions 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> are unformatted input |
| functions. However, it does not really make much sense to construct a |
| sentry object for <tt>gcount()</tt>, <tt>sync()</tt>, ... Also it is |
| unclear what happens to the <tt>gcount()</tt> if |
| eg. <tt>gcount()</tt>, <tt>putback()</tt>, <tt>unget()</tt>, or |
| <tt>sync()</tt> is called: These functions don't extract characters, |
| some of them even "unextract" a character. Should this still |
| be reflected in <tt>gcount()</tt>? Of course, it could be read as if |
| after a call to <tt>gcount()</tt> <tt>gcount()</tt> return <tt>0</tt> |
| (the last unformatted input function, <tt>gcount()</tt>, didn't |
| extract any character) and after a call to <tt>putback()</tt> |
| <tt>gcount()</tt> returns <tt>-1</tt> (the last unformatted input |
| function <tt>putback()</tt> did "extract" back into the |
| stream). Correspondingly for <tt>unget()</tt>. Is this what is |
| intended? If so, this should be clarified. Otherwise, a corresponding |
| clarification should be used.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.1.2.2 [lib.istream.formatted.arithmetic], paragraph 1. |
| Change the beginning of the second sentence from "The conversion |
| occurs" to "These extractors behave as formatted input functions (as |
| described in 27.6.1.2.1). After a sentry object is constructed, |
| the conversion occurs" |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], before paragraph 1. |
| Add an effects clause. "Effects: None. This extractor does |
| not behave as a formatted input function (as described in |
| 27.6.1.2.1). |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], paragraph 2. Change the |
| effects clause to "Effects: Calls pf(*this). This extractor does not |
| behave as a formatted input function (as described in 27.6.1.2.1). |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], paragraph 4. Change the |
| effects clause to "Effects: Calls pf(*this). This extractor does not |
| behave as a formatted input function (as described in 27.6.1.2.1). |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], paragraph 12. Change the |
| first two sentences from "If sb is null, calls setstate(failbit), |
| which may throw ios_base::failure (27.4.4.3). Extracts characters |
| from *this..." to "Behaves as a formatted input function (as described |
| in 27.6.1.2.1). If sb is null, calls setstate(failbit), which may |
| throw ios_base::failure (27.4.4.3). After a sentry object is |
| constructed, extracts characters from *this...". |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], before paragraph 2. Add an |
| effects clause. "Effects: none. This member function does not behave |
| as an unformatted input function (as described in 27.6.1.3, paragraph 1)." |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 3. Change the |
| beginning of the first sentence of the effects clause from "Extracts a |
| character" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts a |
| character" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 5. Change the |
| beginning of the first sentence of the effects clause from "Extracts a |
| character" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts a |
| character" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 7. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| [No change needed in paragraph 10, because it refers to paragraph 7.] |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 12. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| [No change needed in paragraph 15.] |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 17. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| [No change needed in paragraph 23.] |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 24. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], before paragraph 27. Add an |
| Effects clause: "Effects: Behaves as an unformatted input function (as |
| described in 27.6.1.3, paragraph 1). After constructing a sentry |
| object, reads but does not extract the current input character." |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 28. Change the |
| first sentence of the Effects clause from "If !good() calls" to |
| Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() calls" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 30. Change the |
| first sentence of the Effects clause from "If !good() calls" to |
| "Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() calls" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 32. Change the |
| first sentence of the Effects clause from "If !good() calls..." to |
| "Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() |
| calls..." Add a new sentence to the end of the Effects clause: |
| "[Note: this function extracts no characters, so the value returned |
| by the next call to gcount() is 0.]" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 34. Change the |
| first sentence of the Effects clause from "If !good() calls" to |
| "Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() calls". |
| Add a new sentence to the end of the Effects clause: "[Note: this |
| function extracts no characters, so the value returned by the next |
| call to gcount() is 0.]" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 36. Change the |
| first sentence of the Effects clause from "If !rdbuf() is" to "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 rdbuf() is" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], before paragraph 37. Add an |
| Effects clause: "Effects: 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()." Change the first sentence of |
| paragraph 37 from "if fail()" to "after constructing a sentry object, |
| if fail()". |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 38. Change the |
| first sentence of the Effects clause from "If fail()" to "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() |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 40. Change the |
| first sentence of the Effects clause from "If fail()" to "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() |
| </p> |
| |
| <p> |
| In 27.6.2.5.2 [lib.ostream.inserters.arithmetic], paragraph 1. Change |
| the beginning of the third sentence from "The formatting conversion" |
| to "These extractors behave as formatted output functions (as |
| described in 27.6.2.5.1). After the sentry object is constructed, the |
| conversion occurs". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], before paragraph 1. Add an |
| effects clause: "Effects: None. Does not behave as a formatted output |
| function (as described in 27.6.2.5.1).". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], paragraph 2. Change the |
| effects clause to "Effects: calls pf(*this). This extractor does not |
| behave as a formatted output function (as described in 27.6.2.5.1).". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], paragraph 4. Change the |
| effects clause to "Effects: calls pf(*this). This extractor does not |
| behave as a formatted output function (as described in 27.6.2.5.1).". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], paragraph 6. Change the first |
| sentence from "If sb" to "Behaves as a formatted output function (as |
| described in 27.6.2.5.1). After the sentry object is constructed, if |
| sb". |
| </p> |
| |
| <p> |
| In 27.6.2.6 [lib.ostream.unformatted], paragraph 2. Change the first |
| sentence from "Inserts the character" to "Behaves as an unformatted |
| output function (as described in 27.6.2.6, paragraph 1). After |
| constructing a sentry object, inserts the character". |
| </p> |
| |
| <p> |
| In 27.6.2.6 [lib.ostream.unformatted], paragraph 5. Change the first |
| sentence from "Obtains characters" to "Behaves as an unformatted |
| output function (as described in 27.6.2.6, paragraph 1). After |
| constructing a sentry object, obtains characters". |
| </p> |
| |
| <p> |
| In 27.6.2.6 [lib.ostream.unformatted], paragraph 7. Add a new |
| sentence at the end of the paragraph: "Does not behave as an |
| unformatted output function (as described in 27.6.2.6, paragraph 1)." |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>See J16/99-0043==WG21/N1219, Proposed Resolution to Library Issue 60, |
| by Judy Ward and Matt Austern. This proposed resolution is section |
| VI of that paper.</p> |
| <hr> |
| <a name="61"><h3>61. Ambiguity in iostreams exception policy</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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 6 Aug 1998</p> |
| <p>The introduction to the section on unformatted input (27.6.1.3) |
| says that every unformatted input function catches all exceptions that |
| were thrown during input, sets badbit, and then conditionally rethrows |
| the exception. That seems clear enough. Several of the specific |
| functions, however, such as get() and read(), are documented in some |
| circumstances as setting eofbit and/or failbit. (The standard notes, |
| correctly, that setting eofbit or failbit can sometimes result in an |
| exception being thrown.) The question: if one of these functions |
| throws an exception triggered by setting failbit, is this an exception |
| "thrown during input" and hence covered by 27.6.1.3, or does |
| 27.6.1.3 only refer to a limited class of exceptions? Just to make |
| this concrete, suppose you have the following snippet. </p> |
| |
| <pre> |
| char buffer[N]; |
| istream is; |
| ... |
| is.exceptions(istream::failbit); // Throw on failbit but not on badbit. |
| is.read(buffer, N);</pre> |
| |
| <p>Now suppose we reach EOF before we've read N characters. What |
| iostate bits can we expect to be set, and what exception (if any) will |
| be thrown? </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.1.3, paragraph 1, after the sentence that begins |
| "If an exception is thrown...", add the following |
| parenthetical comment: "(Exceptions thrown from |
| <tt>basic_ios<>::clear()</tt> are not caught or rethrown.)" |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG looked to two alternative wordings, and choose the proposed |
| resolution as better standardese.</p> |
| <hr> |
| <a name="62"><h3>62. <tt>Sync</tt>'s return value</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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 6 Aug 1998</p> |
| <p>The Effects clause for sync() (27.6.1.3, paragraph 36) says that it |
| "calls rdbuf()->pubsync() and, if that function returns -1 |
| ... returns traits::eof()." </p> |
| |
| <p>That looks suspicious, because traits::eof() is of type |
| traits::int_type while the return type of sync() is int. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>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 36, change "returns |
| <tt>traits::eof()</tt>" to "returns <tt>-1</tt>". |
| </p> |
| <hr> |
| <a name="63"><h3>63. Exception-handling policy for unformatted output</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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 11 Aug 1998</p> |
| <p>Clause 27 details an exception-handling policy for formatted input, |
| unformatted input, and formatted output. It says nothing for |
| unformatted output (27.6.2.6). 27.6.2.6 should either include the same |
| kind of exception-handling policy as in the other three places, or |
| else it should have a footnote saying that the omission is |
| deliberate. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.2.6, paragraph 1, replace the last sentence ("In any |
| case, the unformatted output function ends by destroying the sentry |
| object, then returning the value specified for the formatted output |
| function.") with the following text: |
| </p> |
| <blockquote> |
| If an exception is thrown during output, then <tt>ios::badbit</tt> is |
| turned on [Footnote: without causing an <tt>ios::failure</tt> to be |
| thrown.] in <tt>*this</tt>'s error state. If <tt>(exceptions() & |
| badbit) != 0</tt> then the exception is rethrown. In any case, the |
| unformatted output function ends by destroying the sentry object, |
| then, if no exception was thrown, returning the value specified for |
| the formatted output function. |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p> |
| This exception-handling policy is consistent with that of formatted |
| input, unformatted input, and formatted output. |
| </p> |
| <hr> |
| <a name="64"><h3>64. Exception handling in <tt>basic_istream::operator>>(basic_streambuf*)</tt> |
| </h3></a><p><b>Section:</b> 27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 11 Aug 1998 </p> |
| <p>27.6.1.2.3, paragraph 13, is ambiguous. It can be interpreted two |
| different ways, depending on whether the second sentence is read as an |
| elaboration of the first. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a>, paragraph 13, which begins |
| "If the function inserts no characters ..." with:</p> |
| |
| <blockquote> |
| <p>If the function inserts no characters, it calls |
| <tt>setstate(failbit)</tt>, which may throw |
| <tt>ios_base::failure</tt> (27.4.4.3). If it inserted no characters |
| because it caught an exception thrown while extracting characters |
| from <tt>sb</tt> and <tt>failbit</tt> is on in <tt>exceptions()</tt> |
| (27.4.4.3), then the caught exception is rethrown. </p> |
| </blockquote> |
| <hr> |
| <a name="66"><h3>66. Strstreambuf::setbuf</h3></a><p><b>Section:</b> D.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstreambuf.virtuals"> [depr.strstreambuf.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 18 Aug 1998</p> |
| <p>D.7.1.3, paragraph 19, says that strstreambuf::setbuf |
| "Performs an operation that is defined separately for each class |
| derived from strstreambuf". This is obviously an incorrect |
| cut-and-paste from basic_streambuf. There are no classes derived from |
| strstreambuf. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>D.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstreambuf.virtuals"> [depr.strstreambuf.virtuals]</a>, paragraph 19, replace the setbuf effects |
| clause which currently says "Performs an operation that is |
| defined separately for each class derived from strstreambuf" |
| with:</p> |
| |
| <blockquote> |
| <p><b>Effects</b>: implementation defined, except that |
| <tt>setbuf(0,0)</tt> has no effect.</p> |
| </blockquote> |
| <hr> |
| <a name="68"><h3>68. Extractors for char* should store null at end</h3></a><p><b>Section:</b> 27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> 14 Jul 1998</p> |
| <p>Extractors for char* (27.6.1.2.3) do not store a null character |
| after the extracted character sequence whereas the unformatted |
| functions like get() do. Why is this?</p> |
| |
| <p>Comment from Jerry Schwarz: There is apparently an editing |
| glitch. You'll notice that the last item of the list of what stops |
| extraction doesn't make any sense. It was supposed to be the line that |
| said a null is stored.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a>, paragraph 7, change the last list |
| item from:</p> |
| |
| <blockquote> |
| A null byte (<tt>charT()</tt>) in the next position, which may be |
| the first position if no characters were extracted. |
| </blockquote> |
| |
| <p>to become a new paragraph which reads:</p> |
| |
| <blockquote> |
| Operator>> then stores a null byte (<tt>charT()</tt>) in the |
| next position, which may be the first position if no characters were |
| extracted. |
| </blockquote> |
| <hr> |
| <a name="69"><h3>69. Must elements of a vector be contiguous?</h3></a><p><b>Section:</b> 23.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.adaptors"> [lib.container.adaptors]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 29 Jul 1998</p> |
| <p>The issue is this: Must the elements of a vector be in contiguous memory?</p> |
| |
| <p>(Please note that this is entirely separate from the question of |
| whether a vector iterator is required to be a pointer; the answer to |
| that question is clearly "no," as it would rule out |
| debugging implementations)</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text to the end of 23.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.adaptors"> [lib.container.adaptors]</a>, |
| paragraph 1. </p> |
| |
| <blockquote> |
| <p>The elements of a vector are stored contiguously, meaning that if |
| v is a <tt>vector<T, Allocator></tt> where T is some type |
| other than <tt>bool</tt>, then it obeys the identity <tt>&v[n] |
| == &v[0] + n</tt> for all <tt>0 <= n < v.size()</tt>.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The LWG feels that as a practical matter the answer is clearly |
| "yes". There was considerable discussion as to the best way |
| to express the concept of "contiguous", which is not |
| directly defined in the standard. Discussion included:</p> |
| |
| <ul> |
| <li>An operational definition similar to the above proposed resolution is |
| already used for valarray (<font color="red">26.3.2.3</font>).</li> |
| <li>There is no need to explicitly consider a user-defined operator& |
| because elements must be copyconstructible (23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> para 3) |
| and copyconstructible (20.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.copyconstructible"> [lib.copyconstructible]</a>) specifies |
| requirements for operator&.</li> |
| <li>There is no issue of one-past-the-end because of language rules.</li> |
| </ul> |
| <hr> |
| <a name="70"><h3>70. Uncaught_exception() missing throw() specification</h3></a><p><b>Section:</b> 18.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.support.exception"> [lib.support.exception]</a>, 18.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.uncaught"> [lib.uncaught]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> Unknown</p> |
| <p>In article 3E04@pratique.fr, Valentin Bonnard writes: </p> |
| |
| <p>uncaught_exception() doesn't have a throw specification.</p> |
| |
| <p>It is intentional ? Does it means that one should be prepared to |
| handle exceptions thrown from uncaught_exception() ?</p> |
| |
| <p>uncaught_exception() is called in exception handling contexts where |
| exception safety is very important.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 15.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/except.html#except.uncaught"> [except.uncaught]</a>, paragraph 1, 18.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.support.exception"> [lib.support.exception]</a>, and 18.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.uncaught"> [lib.uncaught]</a>, add "throw()" to uncaught_exception().</p> |
| <hr> |
| <a name="71"><h3>71. Do_get_monthname synopsis missing argument</h3></a><p><b>Section:</b> 22.2.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.get"> [lib.locale.time.get]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 13 Aug 1998</p> |
| <p>The locale facet member <tt>time_get<>::do_get_monthname</tt> |
| is described in 22.2.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.get.virtuals"> [lib.locale.time.get.virtuals]</a> with five arguments, |
| consistent with do_get_weekday and with its specified use by member |
| get_monthname. However, in the synopsis, it is specified instead with |
| four arguments. The missing argument is the "end" iterator |
| value.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.get"> [lib.locale.time.get]</a>, add an "end" argument to |
| the declaration of member do_monthname as follows:</p> |
| |
| <pre> virtual iter_type do_get_monthname(iter_type s, iter_type end, ios_base&, |
| ios_base::iostate& err, tm* t) const;</pre> |
| <hr> |
| <a name="74"><h3>74. Garbled text for <tt>codecvt::do_max_length</tt> |
| </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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 8 Sep 1998</p> |
| <p>The text of <tt>codecvt::do_max_length</tt>'s "Returns" |
| clause (22.2.1.5.2, paragraph 11) is garbled. It has unbalanced |
| parentheses and a spurious <b>n</b>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace <font color="red">22.2.1.5.2</font> paragraph 11 with the |
| following:</p> |
| |
| <blockquote> |
| <b>Returns</b>: The maximum value that |
| <tt>do_length(state, from, from_end, 1)</tt> can return for any |
| valid range <tt>[from, from_end)</tt> and <tt>stateT</tt> value |
| <tt>state</tt>. The specialization <tt>codecvt<char, char, |
| mbstate_t>::do_max_length()</tt> returns 1. |
| </blockquote> |
| <hr> |
| <a name="75"><h3>75. Contradiction in <tt>codecvt::length</tt>'s argument types</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#TC">TC</a> <b>Submitter:</b> Matt |
| Austern <b>Date:</b> 18 Sep 1998</p> |
| <p>The class synopses for classes <tt>codecvt<></tt> (22.2.1.5) |
| and <tt>codecvt_byname<></tt> (22.2.1.6) say that the first |
| parameter of the member functions <tt>length</tt> and |
| <tt>do_length</tt> is of type <tt>const stateT&</tt>. The member |
| function descriptions, however (22.2.1.5.1, paragraph 6; 22.2.1.5.2, |
| paragraph 9) say that the type is <tt>stateT&</tt>. Either the |
| synopsis or the summary must be changed. </p> |
| |
| <p>If (as I believe) the member function descriptions are correct, |
| then we must also add text saying how <tt>do_length</tt> changes its |
| <tt>stateT</tt> argument. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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>, and also in <font color="red">22.2.1.6</font>, |
| change the <tt>stateT</tt> argument type on both member |
| <tt>length()</tt> and member <tt>do_length()</tt> from </p> |
| |
| <blockquote> |
| <p><tt>const stateT&</tt></p> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <p><tt>stateT&</tt></p> |
| </blockquote> |
| |
| <p>In <font color="red">22.2.1.5.2</font>, add to the definition for member |
| <tt>do_length</tt> a paragraph:</p> |
| |
| <blockquote> |
| <p>Effects: The effect on the <tt>state</tt> argument is ``as if'' |
| it called <tt>do_in(state, from, from_end, from, to, to+max, |
| to)</tt> for <tt>to</tt> pointing to a buffer of at least |
| <tt>max</tt> elements.</p> |
| </blockquote> |
| <hr> |
| <a name="76"><h3>76. Can a <tt>codecvt</tt> facet always convert one internal character at a time?</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#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 25 Sep 1998</p> |
| <p>This issue concerns the requirements on classes derived from |
| <tt>codecvt</tt>, including user-defined classes. What are the |
| restrictions on the conversion from external characters |
| (e.g. <tt>char</tt>) to internal characters (e.g. <tt>wchar_t</tt>)? |
| Or, alternatively, what assumptions about <tt>codecvt</tt> facets can |
| the I/O library make? </p> |
| |
| <p>The question is whether it's possible to convert from internal |
| characters to external characters one internal character at a time, |
| and whether, given a valid sequence of external characters, it's |
| possible to pick off internal characters one at a time. Or, to put it |
| differently: given a sequence of external characters and the |
| corresponding sequence of internal characters, does a position in the |
| internal sequence correspond to some position in the external |
| sequence? </p> |
| |
| <p>To make this concrete, suppose that <tt>[first, last)</tt> is a |
| sequence of <i>M</i> external characters and that <tt>[ifirst, |
| ilast)</tt> is the corresponding sequence of <i>N</i> internal |
| characters, where <i>N > 1</i>. That is, <tt>my_encoding.in()</tt>, |
| applied to <tt>[first, last)</tt>, yields <tt>[ifirst, |
| ilast)</tt>. Now the question: does there necessarily exist a |
| subsequence of external characters, <tt>[first, last_1)</tt>, such |
| that the corresponding sequence of internal characters is the single |
| character <tt>*ifirst</tt>? |
| </p> |
| |
| <p>(What a "no" answer would mean is that |
| <tt>my_encoding</tt> translates sequences only as blocks. There's a |
| sequence of <i>M</i> external characters that maps to a sequence of |
| <i>N</i> internal characters, but that external sequence has no |
| subsequence that maps to <i>N-1</i> internal characters.) </p> |
| |
| <p>Some of the wording in the standard, such as the description of |
| <tt>codecvt::do_max_length</tt> (<font color="red">22.2.1.5.2</font>, |
| paragraph 11) and <tt>basic_filebuf::underflow</tt> (27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a>, paragraph 3) suggests that it must always be |
| possible to pick off internal characters one at a time from a sequence |
| of external characters. However, this is never explicitly stated one |
| way or the other. </p> |
| |
| <p>This issue seems (and is) quite technical, but it is important if |
| we expect users to provide their own encoding facets. This is an area |
| where the standard library calls user-supplied code, so a well-defined |
| set of requirements for the user-supplied code is crucial. Users must |
| be aware of the assumptions that the library makes. This issue affects |
| positioning operations on <tt>basic_filebuf</tt>, unbuffered input, |
| and several of <tt>codecvt</tt>'s member functions. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text as a new paragraph, following <font color="red">22.2.1.5.2</font> paragraph 2:</p> |
| |
| <blockquote> |
| <p>A <tt>codecvt</tt> facet that is used by <tt>basic_filebuf</tt> |
| (27.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.file.streams"> [lib.file.streams]</a>) must have the property that if</p> |
| <pre> do_out(state, from, from_end, from_next, to, to_lim, to_next) |
| </pre> |
| would return <tt>ok</tt>, where <tt>from != from_end</tt>, then |
| <pre> do_out(state, from, from + 1, from_next, to, to_end, to_next) |
| </pre> |
| must also return <tt>ok</tt>, and that if |
| <pre> do_in(state, from, from_end, from_next, to, to_lim, to_next) |
| </pre> |
| would return <tt>ok</tt>, where <tt>to != to_lim</tt>, then |
| <pre> do_in(state, from, from_end, from_next, to, to + 1, to_next) |
| </pre> |
| <p>must also return <tt>ok</tt>. [<i>Footnote:</i> Informally, this |
| means that <tt>basic_filebuf</tt> assumes that the mapping from |
| internal to external characters is 1 to N: a <tt>codecvt</tt> that is |
| used by <tt>basic_filebuf</tt> must be able to translate characters |
| one internal character at a time. <i>--End Footnote</i>]</p> |
| </blockquote> |
| |
| <p><i>[Redmond: Minor change in proposed resolution. Original |
| proposed resolution talked about "success", with a parenthetical |
| comment that success meant returning <tt>ok</tt>. New wording |
| removes all talk about "success", and just talks about the |
| return value.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| |
| <p>The proposed resoluion says that conversions can be performed one |
| internal character at a time. This rules out some encodings that |
| would otherwise be legal. The alternative answer would mean there |
| would be some internal positions that do not correspond to any |
| external file position.</p> |
| <p> |
| An example of an encoding that this rules out is one where the |
| <tt>internT</tt> and <tt>externT</tt> are of the same type, and |
| where the internal sequence <tt>c1 c2</tt> corresponds to the |
| external sequence <tt>c2 c1</tt>. |
| </p> |
| <p>It was generally agreed that <tt>basic_filebuf</tt> relies |
| on this property: it was designed under the assumption that |
| the external-to-internal mapping is N-to-1, and it is not clear |
| that <tt>basic_filebuf</tt> is implementable without that |
| restriction. |
| </p> |
| <p> |
| The proposed resolution is expressed as a restriction on |
| <tt>codecvt</tt> when used by <tt>basic_filebuf</tt>, rather |
| than a blanket restriction on all <tt>codecvt</tt> facets, |
| because <tt>basic_filebuf</tt> is the only other part of the |
| library that uses <tt>codecvt</tt>. If a user wants to define |
| a <tt>codecvt</tt> facet that implements a more general N-to-M |
| mapping, there is no reason to prohibit it, so long as the user |
| does not expect <tt>basic_filebuf</tt> to be able to use it. |
| </p> |
| <hr> |
| <a name="78"><h3>78. Typo: event_call_back</h3></a><p><b>Section:</b> 27.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base"> [lib.ios.base]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>typo: event_call_back should be event_callback </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In the 27.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base"> [lib.ios.base]</a> synopsis change |
| "event_call_back" to "event_callback". </p> |
| <hr> |
| <a name="79"><h3>79. Inconsistent declaration of polar()</h3></a><p><b>Section:</b> 26.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.synopsis"> [lib.complex.synopsis]</a>, 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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>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> polar is declared as follows:</p> |
| <pre> template<class T> complex<T> polar(const T&, const 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> it is declared as follows:</p> |
| <pre> template<class T> complex<T> polar(const T& rho, const T& theta = 0); </pre> |
| |
| <p>Thus whether the second parameter is optional is not clear. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>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> change:</p> |
| <pre> template<class T> complex<T> polar(const T&, const T&);</pre> |
| |
| <p>to:</p> |
| <pre> template<class T> complex<T> polar(const T& rho, const T& theta = 0); </pre> |
| <hr> |
| <a name="80"><h3>80. Global Operators of complex declared twice</h3></a><p><b>Section:</b> 26.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.cfenv.syn"> [lib.cfenv.syn]</a>, 26.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.fenv"> [lib.fenv]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>Both 26.2.1 and 26.2.2 contain declarations of global operators for |
| class complex. This redundancy should be removed.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Reduce redundancy according to the general style of the standard. </p> |
| <hr> |
| <a name="83"><h3>83. String::npos vs. string::max_size()</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#TC">TC</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>Many string member functions throw if size is getting or exceeding |
| npos. However, I wonder why they don't throw if size is getting or |
| exceeding max_size() instead of npos. May be npos is known at compile |
| time, while max_size() is known at runtime. However, what happens if |
| size exceeds max_size() but not npos, then? It seems the standard |
| lacks some clarifications here.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>After 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a> paragraph 4 ("The functions |
| described in this clause...") add a new paragraph:</p> |
| |
| <blockquote> |
| <p>For any string operation, if as a result of the operation, <tt> size()</tt> would exceed |
| <tt> max_size()</tt> then |
| the operation throws <tt>length_error</tt>.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes length_error is the correct exception to throw.</p> |
| <hr> |
| <a name="86"><h3>86. String constructors don't describe exceptions</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#TC">TC</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>The constructor from a range:</p> |
| |
| <pre>template<class InputIterator> |
| basic_string(InputIterator begin, InputIterator end, |
| const Allocator& a = Allocator());</pre> |
| |
| <p>lacks a throws clause. However, I would expect that it throws |
| according to the other constructors if the numbers of characters in |
| the range equals npos (or exceeds max_size(), see above). </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 21.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.cons"> [lib.string.cons]</a>, Strike throws paragraphs for |
| constructors which say "Throws: length_error if n == |
| npos."</p> |
| <p><b>Rationale:</b></p> |
| <p>Throws clauses for length_error if n == npos are no longer needed |
| because they are subsumed by the general wording added by the |
| resolution for issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#83">83</a>.</p> |
| <hr> |
| <a name="90"><h3>90. Incorrect description of operator >> for strings</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#TC">TC</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>The effect of operator >> for strings contain the following item:</p> |
| |
| <p> <tt>isspace(c,getloc())</tt> is true for the next available input |
| character c.</p> |
| |
| <p>Here <tt>getloc()</tt> has to be replaced by <tt>is.getloc()</tt>. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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> paragraph 1 Effects clause replace:</p> |
| |
| <blockquote> |
| <p><tt>isspace(c,getloc())</tt> is true for the next available input character c.</p> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <p><tt>isspace(c,is.getloc())</tt> is true for the next available input character c.</p> |
| </blockquote> |
| <hr> |
| <a name="91"><h3>91. Description of operator>> and getline() for string<> might cause endless loop</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#WP">WP</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>Operator >> and getline() for strings read until eof() |
| in the input stream is true. However, this might never happen, if the |
| stream can't read anymore without reaching EOF. So shouldn't it be |
| changed into that it reads until !good() ? </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 21.3.7.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.io"> [lib.string.io]</a>, paragraph 1, replace:</p> |
| <blockquote> |
| Effects: Begins by constructing a sentry object k as if k were |
| constructed by typename basic_istream<charT,traits>::sentry k( is). If |
| bool( k) is true, it calls str.erase() and then extracts characters |
| from is and appends them to str as if by calling str.append(1, c). If |
| is.width() is greater than zero, the maximum number n of characters |
| appended is is.width(); otherwise n is str.max_size(). Characters are |
| extracted and appended until any of the following occurs: |
| </blockquote> |
| <p>with:</p> |
| <blockquote> |
| Effects: Behaves as a formatted input function (27.6.1.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.reqmts"> [lib.istream.formatted.reqmts]</a>). After constructing a sentry object, if the |
| sentry converts to true, calls str.erase() and then extracts |
| characters from is and appends them to str as if by calling |
| str.append(1,c). If is.width() is greater than zero, the maximum |
| number n of characters appended is is.width(); otherwise n is |
| str.max_size(). Characters are extracted and appended until any of the |
| following occurs: |
| </blockquote> |
| |
| <p>In 21.3.7.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.io"> [lib.string.io]</a>, paragraph 6, replace</p> |
| <blockquote> |
| Effects: Begins by constructing a sentry object k as if by typename |
| basic_istream<charT,traits>::sentry k( is, true). If bool( k) is true, |
| it calls str.erase() and then extracts characters from is and appends |
| them to str as if by calling str.append(1, c) until any of the |
| following occurs: |
| </blockquote> |
| <p>with:</p> |
| <blockquote> |
| Effects: Behaves as an unformatted input function (27.6.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.unformatted"> [lib.istream.unformatted]</a>), except that it does not affect the value returned |
| by subsequent calls to basic_istream<>::gcount(). After |
| constructing a sentry object, if the sentry converts to true, calls |
| str.erase() and then extracts characters from is and appends them to |
| str as if by calling str.append(1,c) until any of the following |
| occurs: |
| </blockquote> |
| |
| <p><i>[Redmond: Made changes in proposed resolution. <tt>operator>></tt> |
| should be a formatted input function, not an unformatted input function. |
| <tt>getline</tt> should not be required to set <tt>gcount</tt>, since |
| there is no mechanism for <tt>gcount</tt> to be set except by one of |
| <tt>basic_istream</tt>'s member functions.]</i></p> |
| |
| <p><i>[Curaçao: Nico agrees with proposed resolution.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The real issue here is whether or not these string input functions |
| get their characters from a streambuf, rather than by calling an |
| istream's member functions, a streambuf signals failure either by |
| returning eof or by throwing an exception; there are no other |
| possibilities. The proposed resolution makes it clear that these two |
| functions do get characters from a streambuf.</p> |
| <hr> |
| <a name="92"><h3>92. Incomplete Algorithm Requirements</h3></a><p><b>Section:</b> 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#WP">WP</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p> |
| <p>The standard does not state, how often a function object is copied, |
| called, or the order of calls inside an algorithm. This may lead to |
| surprising/buggy behavior. Consider the following example: </p> |
| |
| <pre>class Nth { // function object that returns true for the nth element |
| private: |
| int nth; // element to return true for |
| int count; // element counter |
| public: |
| Nth (int n) : nth(n), count(0) { |
| } |
| bool operator() (int) { |
| return ++count == nth; |
| } |
| }; |
| .... |
| // remove third element |
| list<int>::iterator pos; |
| pos = remove_if(coll.begin(),coll.end(), // range |
| Nth(3)), // remove criterion |
| coll.erase(pos,coll.end()); </pre> |
| |
| <p>This call, in fact removes the 3rd <b>AND the 6th</b> element. This |
| happens because the usual implementation of the algorithm copies the |
| function object internally: </p> |
| |
| <pre>template <class ForwIter, class Predicate> |
| ForwIter std::remove_if(ForwIter beg, ForwIter end, Predicate op) |
| { |
| beg = find_if(beg, end, op); |
| if (beg == end) { |
| return beg; |
| } |
| else { |
| ForwIter next = beg; |
| return remove_copy_if(++next, end, beg, op); |
| } |
| } </pre> |
| |
| <p>The algorithm uses find_if() to find the first element that should |
| be removed. However, it then uses a copy of the passed function object |
| to process the resulting elements (if any). Here, Nth is used again |
| and removes also the sixth element. This behavior compromises the |
| advantage of function objects being able to have a state. Without any |
| cost it could be avoided (just implement it directly instead of |
| calling find_if()). </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add a new paragraph following 25 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a> paragraph 8:</p> |
| <blockquote> |
| [Note: Unless otherwise specified, algorithms that take function |
| objects as arguments are permitted to copy those function objects |
| freely. Programmers for whom object identity is important should |
| consider using a wrapper class that points to a noncopied |
| implementation object, or some equivalent solution.] |
| </blockquote> |
| |
| <p><i>[Dublin: Pete Becker felt that this may not be a defect, |
| but rather something that programmers need to be educated about. |
| There was discussion of adding wording to the effect that the number |
| and order of calls to function objects, including predicates, not |
| affect the behavior of the function object.]</i></p> |
| |
| <p><i>[Pre-Kona: Nico comments: It seems the problem is that we don't |
| have a clear statement of "predicate" in the |
| standard. People including me seemed to think "a function |
| returning a Boolean value and being able to be called by an STL |
| algorithm or be used as sorting criterion or ... is a |
| predicate". But a predicate has more requirements: It should |
| never change its behavior due to a call or being copied. IMHO we have |
| to state this in the standard. If you like, see section 8.1.4 of my |
| library book for a detailed discussion.]</i></p> |
| |
| <p><i>[Kona: Nico will provide wording to the effect that "unless |
| otherwise specified, the number of copies of and calls to function |
| objects by algorithms is unspecified". Consider placing in |
| 25 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a> after paragraph 9.]</i></p> |
| |
| <p><i>[Santa Cruz: The standard doesn't currently guarantee that |
| functions object won't be copied, and what isn't forbidden is |
| allowed. It is believed (especially since implementations that were |
| written in concert with the standard do make copies of function |
| objects) that this was intentional. Thus, no normative change is |
| needed. What we should put in is a non-normative note suggesting to |
| programmers that if they want to guarantee the lack of copying they |
| should use something like the <tt>ref</tt> wrapper.]</i></p> |
| |
| <p><i>[Oxford: Matt provided wording.]</i></p> |
| |
| |
| <hr> |
| <a name="98"><h3>98. Input iterator requirements are badly written</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#WP">WP</a> <b>Submitter:</b> AFNOR <b>Date:</b> 7 Oct 1998</p> |
| <p>Table 72 in 24.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.input.iterators"> [lib.input.iterators]</a> specifies semantics for |
| <tt>*r++</tt> of:</p> |
| |
| <p> <tt>{ T tmp = *r; ++r; return tmp; }</tt></p> |
| |
| <p>There are two problems with this. First, the return type is |
| specified to be "T", as opposed to something like "convertible to T". |
| This is too specific: we want to allow *r++ to return an lvalue.</p> |
| |
| <p>Second, writing the semantics in terms of code misleadingly |
| suggests that the effects *r++ should precisely replicate the behavior |
| of this code, including side effects. (Does this mean that *r++ |
| should invoke the copy constructor exactly as many times as the sample |
| code above would?) See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#334">334</a> for a similar |
| problem.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| In Table 72 in 24.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.input.iterators"> [lib.input.iterators]</a>, change the return type |
| for <tt>*r++</tt> from <tt>T</tt> to "convertible to T". |
| <p><b>Rationale:</b></p> |
| <p>This issue has two parts: the return type, and the number of times |
| the copy constructor is invoked.</p> |
| |
| <p>The LWG believes the the first part is a real issue. It's |
| inappropriate for the return type to be specified so much more |
| precisely for *r++ than it is for *r. In particular, if r is of |
| (say) type <tt>int*</tt>, then *r++ isn't <tt>int</tt>, |
| but <tt>int&</tt>.</p> |
| |
| <p>The LWG does not believe that the number of times the copy |
| constructor is invoked is a real issue. This can vary in any case, |
| because of language rules on copy constructor elision. That's too |
| much to read into these semantics clauses.</p> |
| |
| <p>Additionally, as Dave Abrahams pointed out (c++std-lib-13703): since |
| we're told (24.1/3) that forward iterators satisfy all the requirements |
| of input iterators, we can't impose any requirements in the Input |
| Iterator requirements table that forward iterators don't satisfy.</p> |
| <hr> |
| <a name="103"><h3>103. set::iterator is required to be modifiable, but this allows modification of keys</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#WP">WP</a> <b>Submitter:</b> AFNOR <b>Date:</b> 7 Oct 1998</p> |
| <p>Set::iterator is described as implementation-defined with a |
| reference to the container requirement; the container requirement says |
| that const_iterator is an iterator pointing to const T and iterator an |
| iterator pointing to T.</p> |
| |
| <p>23.1.2 paragraph 2 implies that the keys should not be modified to |
| break the ordering of elements. But that is not clearly |
| specified. Especially considering that the current standard requires |
| that iterator for associative containers be different from |
| const_iterator. Set, for example, has the following: </p> |
| |
| <p><tt>typedef implementation defined iterator;<br> |
| // See _lib.container.requirements_</tt></p> |
| |
| <p>23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> actually requires that iterator type pointing |
| to T (table 65). Disallowing user modification of keys by changing the |
| standard to require an iterator for associative container to be the |
| same as const_iterator would be overkill since that will unnecessarily |
| significantly restrict the usage of associative container. A class to |
| be used as elements of set, for example, can no longer be modified |
| easily without either redesigning the class (using mutable on fields |
| that have nothing to do with ordering), or using const_cast, which |
| defeats requiring iterator to be const_iterator. The proposed solution |
| goes in line with trusting user knows what he is doing. </p> |
| |
| <p><b>Other Options Evaluated:</b> </p> |
| |
| <p>Option A. 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>, paragraph 2, after |
| first sentence, and before "In addition,...", add one line: |
| </p> |
| |
| <blockquote> |
| <p>Modification of keys shall not change their strict weak ordering. </p> |
| </blockquote> |
| |
| <p>Option B. Add three new sentences to 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a>:</p> |
| |
| <blockquote> |
| <p>At the end of paragraph 5: "Keys in an associative container |
| are immutable." At the end of paragraph 6: "For |
| associative containers where the value type is the same as the key |
| type, both <tt>iterator</tt> and <tt>const_iterator</tt> are |
| constant iterators. It is unspecified whether or not |
| <tt>iterator</tt> and <tt>const_iterator</tt> are the same |
| type."</p> |
| </blockquote> |
| |
| <p>Option C. To 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a>, paragraph 3, which |
| currently reads:</p> |
| |
| <blockquote> |
| <p>The phrase ``equivalence of keys'' means the equivalence relation imposed by the |
| comparison and not the operator== on keys. That is, two keys k1 and k2 in the same |
| container are considered to be equivalent if for the comparison object comp, comp(k1, k2) |
| == false && comp(k2, k1) == false.</p> |
| </blockquote> |
| |
| <p> add the following:</p> |
| |
| <blockquote> |
| <p>For any two keys k1 and k2 in the same container, comp(k1, k2) shall return the same |
| value whenever it is evaluated. [Note: If k2 is removed from the container and later |
| reinserted, comp(k1, k2) must still return a consistent value but this value may be |
| different than it was the first time k1 and k2 were in the same container. This is |
| intended to allow usage like a string key that contains a filename, where comp compares |
| file contents; if k2 is removed, the file is changed, and the same k2 (filename) is |
| reinserted, comp(k1, k2) must again return a consistent value but this value may be |
| different than it was the previous time k2 was in the container.]</p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following to 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> at |
| the indicated location:</p> |
| |
| <blockquote> |
| <p>At the end of paragraph 3: "For any two keys k1 and k2 in the same container, |
| calling comp(k1, k2) shall always return the same |
| value."</p> |
| <p>At the end of paragraph 5: "Keys in an associative container are immutable."</p> |
| <p>At the end of paragraph 6: "For associative containers where the value type is the |
| same as the key type, both <tt>iterator</tt> and <tt>const_iterator</tt> are constant |
| iterators. It is unspecified whether or not <tt>iterator</tt> and <tt>const_iterator</tt> |
| are the same type."</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Several arguments were advanced for and against allowing set elements to be |
| mutable as long as the ordering was not effected. The argument which swayed the |
| LWG was one of safety; if elements were mutable, there would be no compile-time |
| way to detect of a simple user oversight which caused ordering to be |
| modified. There was a report that this had actually happened in practice, |
| and had been painful to diagnose. If users need to modify elements, |
| it is possible to use mutable members or const_cast.</p> |
| |
| <p>Simply requiring that keys be immutable is not sufficient, because the comparison |
| object may indirectly (via pointers) operate on values outside of the keys.</p> |
| |
| <p> |
| The types <tt>iterator</tt> and <tt>const_iterator</tt> are permitted |
| to be different types to allow for potential future work in which some |
| member functions might be overloaded between the two types. No such |
| member functions exist now, and the LWG believes that user functionality |
| will not be impaired by permitting the two types to be the same. A |
| function that operates on both iterator types can be defined for |
| <tt>const_iterator</tt> alone, and can rely on the automatic |
| conversion from <tt>iterator</tt> to <tt>const_iterator</tt>. |
| </p> |
| |
| <p><i>[Tokyo: The LWG crafted the proposed resolution and rationale.]</i></p> |
| <hr> |
| <a name="106"><h3>106. Numeric library private members are implementation defined</h3></a><p><b>Section:</b> 26.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.member.ops"> [lib.complex.member.ops]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> AFNOR <b>Date:</b> 7 Oct 1998</p> |
| <p>This is the only place in the whole standard where the implementation has to document |
| something private.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove the comment which says "// remainder implementation defined" from: |
| </p> |
| |
| <ul> |
| <li>26.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.member.ops"> [lib.complex.member.ops]</a> |
| </li> |
| <li>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> |
| </li> |
| <li>26.3.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.transcendentals"> [lib.complex.transcendentals]</a> |
| </li> |
| <li>26.3.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.cmplx.over"> [lib.cmplx.over]</a> |
| </li> |
| </ul> |
| <hr> |
| <a name="108"><h3>108. Lifetime of exception::what() return unspecified</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#TC">TC</a> <b>Submitter:</b> AFNOR <b>Date:</b> 7 Oct 1998</p> |
| <p>In 18.6.1, paragraphs 8-9, the lifetime of the return value of |
| exception::what() is left unspecified. This issue has implications |
| with exception safety of exception handling: some exceptions should |
| not throw bad_alloc.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to 18.6.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.type.info"> [lib.type.info]</a> paragraph 9 (exception::what notes |
| clause) the sentence:</p> |
| |
| <blockquote> |
| <p>The return value remains valid until the exception object from which it is obtained is |
| destroyed or a non-const member function of the exception object is called.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>If an exception object has non-const members, they may be used |
| to set internal state that should affect the contents of the string |
| returned by <tt>what()</tt>. |
| </p> |
| <hr> |
| <a name="109"><h3>109. Missing binders for non-const sequence elements</h3></a><p><b>Section:</b> 20.5.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.arithmetic.operations"> [lib.arithmetic.operations]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Bjarne Stroustrup <b>Date:</b> 7 Oct 1998</p> |
| |
| <p>There are no versions of binders that apply to non-const elements |
| of a sequence. This makes examples like for_each() using bind2nd() on |
| page 521 of "The C++ Programming Language (3rd)" |
| non-conforming. Suitable versions of the binders need to be added.</p> |
| |
| <p>Further discussion from Nico:</p> |
| |
| <p>What is probably meant here is shown in the following example:</p> |
| |
| <pre>class Elem { |
| public: |
| void print (int i) const { } |
| void modify (int i) { } |
| }; </pre> |
| <pre>int main() |
| { |
| vector<Elem> coll(2); |
| for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&Elem::print),42)); // OK |
| for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&Elem::modify),42)); // ERROR |
| }</pre> |
| |
| <p>The error results from the fact that bind2nd() passes its first |
| argument (the argument of the sequence) as constant reference. See the |
| following typical implementation:</p> |
| |
| <blockquote> |
| <pre>template <class Operation> |
| class binder2nd |
| : public unary_function<typename Operation::first_argument_type, |
| typename Operation::result_type> { |
| protected: |
| Operation op; |
| typename Operation::second_argument_type value; |
| public: |
| binder2nd(const Operation& o, |
| const typename Operation::second_argument_type& v) |
| : op(o), value(v) {} </pre> |
| <pre> typename Operation::result_type |
| operator()(const typename Operation::first_argument_type& x) const { |
| return op(x, value); |
| } |
| };</pre> |
| </blockquote> |
| |
| <p>The solution is to overload operator () of bind2nd for non-constant arguments:</p> |
| |
| <blockquote> |
| <pre>template <class Operation> |
| class binder2nd |
| : public unary_function<typename Operation::first_argument_type, |
| typename Operation::result_type> { |
| protected: |
| Operation op; |
| typename Operation::second_argument_type value; |
| public: |
| binder2nd(const Operation& o, |
| const typename Operation::second_argument_type& v) |
| : op(o), value(v) {} </pre> |
| <pre> typename Operation::result_type |
| operator()(const typename Operation::first_argument_type& x) const { |
| return op(x, value); |
| } |
| typename Operation::result_type |
| operator()(typename Operation::first_argument_type& x) const { |
| return op(x, value); |
| } |
| };</pre> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><b>Howard believes there is a flaw</b> in this resolution. |
| See c++std-lib-9127. We may need to reopen this issue.</p> |
| |
| <p>In <font color="red">20.5.6.1</font> in the declaration of binder1st after:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(const typename Operation::second_argument_type& x) const;</tt></p> |
| </blockquote> |
| <p>insert:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(typename Operation::second_argument_type& x) const;</tt></p> |
| </blockquote> |
| <p>In <font color="red">20.5.6.3</font> in the declaration of binder2nd after:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(const typename Operation::first_argument_type& x) const;</tt></p> |
| </blockquote> |
| <p>insert:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(typename Operation::first_argument_type& x) const;</tt></p> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG discussed this at some length.It was agreed that |
| this is a mistake in the design, but there was no consensus on whether |
| it was a defect in the Standard. Straw vote: NAD - 5. Accept |
| proposed resolution - 3. Leave open - 6.]</i></p> |
| |
| <p><i>[Copenhagen: It was generally agreed that this was a defect. |
| Strap poll: NAD - 0. Accept proposed resolution - 10. |
| Leave open - 1.]</i></p> |
| |
| <hr> |
| <a name="110"><h3>110. istreambuf_iterator::equal not const</h3></a><p><b>Section:</b> 24.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator"> [lib.istreambuf.iterator]</a>, 24.5.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator::equal"> [lib.istreambuf.iterator::equal]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 15 Oct 1998</p> |
| <p>Member istreambuf_iterator<>::equal is not declared |
| "const", yet 24.5.3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator::op=="> [lib.istreambuf.iterator::op==]</a> says that operator==, |
| which is const, calls it. This is contradictory. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator"> [lib.istreambuf.iterator]</a> and also in 24.5.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator::equal"> [lib.istreambuf.iterator::equal]</a>, |
| replace:</p> |
| |
| <blockquote> |
| <pre>bool equal(istreambuf_iterator& b);</pre> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <pre>bool equal(const istreambuf_iterator& b) const;</pre> |
| </blockquote> |
| <hr> |
| <a name="112"><h3>112. Minor typo in <tt>ostreambuf_iterator</tt> constructor</h3></a><p><b>Section:</b> 24.5.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.ostreambuf.iter.cons"> [lib.ostreambuf.iter.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 20 Oct 1998</p> |
| <p>The <b>requires</b> clause for <tt>ostreambuf_iterator</tt>'s |
| constructor from an <tt>ostream_type</tt> (24.5.4.1, paragraph 1) |
| reads "<i>s</i> is not null". However, <i>s</i> is a |
| reference, and references can't be null. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.5.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.ostreambuf.iter.cons"> [lib.ostreambuf.iter.cons]</a>:</p> |
| |
| <p>Move the current paragraph 1, which reads "Requires: s is not |
| null.", from the first constructor to the second constructor.</p> |
| |
| <p>Insert a new paragraph 1 Requires clause for the first constructor |
| reading:</p> |
| |
| <blockquote> |
| <p><b>Requires</b>: <tt>s.rdbuf()</tt> is not null.</p> |
| </blockquote> |
| <hr> |
| <a name="114"><h3>114. Placement forms example in error twice</h3></a><p><b>Section:</b> 18.5.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete.placement"> [lib.new.delete.placement]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 28 Oct 1998</p> |
| <p>Section 18.5.1.3 contains the following example: </p> |
| |
| <pre>[Example: This can be useful for constructing an object at a known address: |
| char place[sizeof(Something)]; |
| Something* p = new (place) Something(); |
| -end example]</pre> |
| |
| <p>First code line: "place" need not have any special alignment, and the |
| following constructor could fail due to misaligned data.</p> |
| |
| <p>Second code line: Aren't the parens on Something() incorrect? [Dublin: the LWG |
| believes the () are correct.]</p> |
| |
| <p>Examples are not normative, but nevertheless should not show code that is invalid or |
| likely to fail.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the <u> first line of code</u> in the example in |
| 18.5.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete.placement"> [lib.new.delete.placement]</a> with: |
| </p> |
| |
| <blockquote> |
| <pre>void* place = operator new(sizeof(Something));</pre> |
| </blockquote> |
| <hr> |
| <a name="115"><h3>115. Typo in strstream constructors</h3></a><p><b>Section:</b> D.7.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstream.cons"> [depr.strstream.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 2 Nov 1998</p> |
| <p>D.7.4.1 strstream constructors paragraph 2 says: </p> |
| |
| <blockquote> |
| <p>Effects: Constructs an object of class strstream, initializing the base class with |
| iostream(& sb) and initializing sb with one of the two constructors: </p> |
| <p>- If mode&app==0, then s shall designate the first element of an array of n |
| elements. The constructor is strstreambuf(s, n, s). </p> |
| <p>- If mode&app==0, then s shall designate the first element of an array of n |
| elements that contains an NTBS whose first element is designated by s. The constructor is |
| strstreambuf(s, n, s+std::strlen(s)).</p> |
| </blockquote> |
| |
| <p>Notice the second condition is the same as the first. I think the second condition |
| should be "If mode&app==app", or "mode&app!=0", meaning that |
| the append bit is set.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In D.7.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.ostrstream.cons"> [depr.ostrstream.cons]</a> paragraph 2 and D.7.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.strstream.cons"> [depr.strstream.cons]</a> |
| paragraph 2, change the first condition to <tt>(mode&app)==0</tt> |
| and the second condition to <tt>(mode&app)!=0</tt>.</p> |
| <hr> |
| <a name="117"><h3>117. <tt>basic_ostream</tt> uses nonexistent <tt>num_put</tt> member functions</h3></a><p><b>Section:</b> 27.6.2.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.inserters.arithmetic"> [lib.ostream.inserters.arithmetic]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 20 Nov 1998</p> |
| <p>The <b>effects</b> clause for numeric inserters says that |
| insertion of a value <tt>x</tt>, whose type is either <tt>bool</tt>, |
| <tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, <tt>unsigned |
| int</tt>, <tt>long</tt>, <tt>unsigned long</tt>, <tt>float</tt>, |
| <tt>double</tt>, <tt>long double</tt>, or <tt>const void*</tt>, is |
| delegated to <tt>num_put</tt>, and that insertion is performed as if |
| through the following code fragment: </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), val). failed();</pre> |
| |
| <p>This doesn't work, because <tt>num_put<></tt>::put is only |
| overloaded for the types <tt>bool</tt>, <tt>long</tt>, <tt>unsigned |
| long</tt>, <tt>double</tt>, <tt>long double</tt>, and <tt>const |
| void*</tt>. That is, the code fragment in the standard is incorrect |
| (it is diagnosed as ambiguous at compile time) for the types |
| <tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, <tt>unsigned |
| int</tt>, and <tt>float</tt>. </p> |
| |
| <p>We must either add new member functions to <tt>num_put</tt>, or |
| else change the description in <tt>ostream</tt> so that it only calls |
| functions that are actually there. I prefer the latter. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 27.6.2.5.2, paragraph 1 with the following: </p> |
| |
| <blockquote> |
| <p> |
| The classes num_get<> and num_put<> handle localeÂdependent numeric |
| formatting and parsing. These inserter functions use the imbued |
| locale value to perform numeric formatting. When val is of type bool, |
| long, unsigned long, double, long double, or const void*, the |
| formatting conversion occurs as if it performed the following code |
| fragment: |
| </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), val). failed(); |
| </pre> |
| |
| <p> |
| When val is of type short the formatting conversion occurs as if it |
| performed the following code fragment: |
| </p> |
| |
| <pre>ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; |
| bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), |
| baseflags == ios_base::oct || baseflags == ios_base::hex |
| ? static_cast<long>(static_cast<unsigned short>(val)) |
| : static_cast<long>(val)). failed(); |
| </pre> |
| |
| <p> |
| When val is of type int the formatting conversion occurs as if it performed |
| the following code fragment: |
| </p> |
| |
| <pre>ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; |
| bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), |
| baseflags == ios_base::oct || baseflags == ios_base::hex |
| ? static_cast<long>(static_cast<unsigned int>(val)) |
| : static_cast<long>(val)). failed(); |
| </pre> |
| |
| <p> |
| When val is of type unsigned short or unsigned int the formatting conversion |
| occurs as if it performed the following code fragment: |
| </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), static_cast<unsigned long>(val)). |
| failed(); |
| </pre> |
| |
| <p> |
| When val is of type float the formatting conversion occurs as if it |
| performed the following code fragment: |
| </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), static_cast<double>(val)). |
| failed(); |
| </pre> |
| |
| </blockquote> |
| |
| <p><i>[post-Toronto: This differs from the previous proposed |
| resolution; PJP provided the new wording. The differences are in |
| signed short and int output.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution was to cast int and short to long, |
| unsigned int and unsigned short to unsigned long, and float to double, |
| thus ensuring that we don't try to use nonexistent num_put<> |
| member functions. The current proposed resolution is more |
| complicated, but gives more expected results for hex and octal output |
| of signed short and signed int. (On a system with 16-bit short, for |
| example, printing short(-1) in hex format should yield 0xffff.)</p> |
| <hr> |
| <a name="118"><h3>118. <tt>basic_istream</tt> uses nonexistent <tt>num_get</tt> member functions</h3></a><p><b>Section:</b> 27.6.1.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.arithmetic"> [lib.istream.formatted.arithmetic]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 20 Nov 1998</p> |
| <p>Formatted input is defined for the types <tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, |
| <tt>unsigned int</tt>, <tt>long</tt>, <tt>unsigned long</tt>, <tt>float</tt>, <tt>double</tt>, |
| <tt>long double</tt>, <tt>bool</tt>, and <tt>void*</tt>. According to section 27.6.1.2.2, |
| formatted input of a value <tt>x</tt> is done as if by the following code fragment: </p> |
| |
| <pre>typedef num_get< charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| use_facet< numget >(loc).get(*this, 0, *this, err, val); |
| setstate(err);</pre> |
| |
| <p>According to section 22.2.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.members"> [lib.facet.num.get.members]</a>, however, |
| <tt>num_get<>::get()</tt> is only overloaded for the types |
| <tt>bool</tt>, <tt>long</tt>, <tt>unsigned short</tt>, <tt>unsigned |
| int</tt>, <tt>unsigned long</tt>, <tt>unsigned long</tt>, |
| <tt>float</tt>, <tt>double</tt>, <tt>long double</tt>, and |
| <tt>void*</tt>. Comparing the lists from the two sections, we find |
| that 27.6.1.2.2 is using a nonexistent function for types |
| <tt>short</tt> and <tt>int</tt>. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.arithmetic"> [lib.istream.formatted.arithmetic]</a> Arithmetic Extractors, remove the |
| two lines (1st and 3rd) which read:</p> |
| <blockquote> |
| <pre>operator>>(short& val); |
| ... |
| operator>>(int& val);</pre> |
| </blockquote> |
| |
| <p>And add the following at the end of that section (27.6.1.2.2) :</p> |
| |
| <blockquote> |
| <pre>operator>>(short& val);</pre> |
| <p>The conversion occurs as if performed by the following code fragment (using |
| the same notation as for the preceding code fragment):</p> |
| <pre> typedef num_get< charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| long lval; |
| use_facet< numget >(loc).get(*this, 0, *this, err, lval); |
| if (err == 0 |
| && (lval < numeric_limits<short>::min() || numeric_limits<short>::max() < lval)) |
| err = ios_base::failbit; |
| setstate(err);</pre> |
| <pre>operator>>(int& val);</pre> |
| <p>The conversion occurs as if performed by the following code fragment (using |
| the same notation as for the preceding code fragment):</p> |
| <pre> typedef num_get< charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| long lval; |
| use_facet< numget >(loc).get(*this, 0, *this, err, lval); |
| if (err == 0 |
| && (lval < numeric_limits<int>::min() || numeric_limits<int>::max() < lval)) |
| err = ios_base::failbit; |
| setstate(err);</pre> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: PJP provided the above wording.]</i></p> |
| <hr> |
| <a name="119"><h3>119. Should virtual functions be allowed to strengthen the exception specification?</h3></a><p><b>Section:</b> 17.4.4.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.exception.handling"> [lib.res.on.exception.handling]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998</p> |
| <p>Section 17.4.4.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.exception.handling"> [lib.res.on.exception.handling]</a> states: </p> |
| |
| <p>"An implementation may strengthen the exception-specification |
| for a function by removing listed exceptions." </p> |
| |
| <p>The problem is that if an implementation is allowed to do this for |
| virtual functions, then a library user cannot write a class that |
| portably derives from that class. </p> |
| |
| <p>For example, this would not compile if ios_base::failure::~failure |
| had an empty exception specification: </p> |
| |
| <pre>#include <ios> |
| #include <string> |
| |
| class D : public std::ios_base::failure { |
| public: |
| D(const std::string&); |
| ~D(); // error - exception specification must be compatible with |
| // overridden virtual function ios_base::failure::~failure() |
| };</pre> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change Section 17.4.4.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.exception.handling"> [lib.res.on.exception.handling]</a> from:</p> |
| |
| <p> "may strengthen the |
| exception-specification for a function"</p> |
| |
| <p>to:</p> |
| |
| <p> "may strengthen the |
| exception-specification for a non-virtual function". </p> |
| <hr> |
| <a name="120"><h3>120. Can an implementor add specializations?</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#WP">WP</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998</p> |
| |
| <p>The original issue asked whether a library implementor could |
| specialize standard library templates for built-in types. (This was |
| an issue because users are permitted to explicitly instantiate |
| standard library templates.)</p> |
| |
| <p>Specializations are no longer a problem, because of the resolution |
| to core issue 259. Under the proposed resolution, it will be legal |
| for a translation unit to contain both a specialization and an |
| explicit instantiation of the same template, provided that the |
| specialization comes first. In such a case, the explicit |
| instantiation will be ignored. Further discussion of library issue |
| 120 assumes that the core 259 resolution will be adopted.</p> |
| |
| <p>However, as noted in lib-7047, one piece of this issue still |
| remains: what happens if a standard library implementor explicitly |
| instantiates a standard library templates? It's illegal for a program |
| to contain two different explicit instantiations of the same template |
| for the same type in two different translation units (ODR violation), |
| and the core working group doesn't believe it is practical to relax |
| that restriction.</p> |
| |
| <p>The issue, then, is: are users allowed to explicitly instantiate |
| standard library templates for non-user defined types? The status quo |
| answer is 'yes'. Changing it to 'no' would give library implementors |
| more freedom.</p> |
| |
| <p>This is an issue because, for performance reasons, library |
| implementors often need to explicitly instantiate standard library |
| templates. (for example, std::basic_string<char>) Does giving |
| users freedom to explicitly instantiate standard library templates for |
| non-user defined types make it impossible or painfully difficult for |
| library implementors to do this?</p> |
| |
| <p>John Spicer suggests, in lib-8957, that library implementors have a |
| mechanism they can use for explicit instantiations that doesn't |
| prevent users from performing their own explicit instantiations: put |
| each explicit instantiation in its own object file. (Different |
| solutions might be necessary for Unix DSOs or MS-Windows DLLs.) On |
| some platforms, library implementors might not need to do anything |
| special: the "undefined behavior" that results from having two |
| different explicit instantiations might be harmless.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Append to 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> paragraph 1: </p> |
| <blockquote> |
| A program may explicitly instantiate any templates in the standard |
| library only if the declaration depends on the name of a user-defined |
| type of external linkage and the instantiation meets the standard library |
| requirements for the original template. |
| </blockquote> |
| |
| <p><i>[Kona: changed the wording from "a user-defined name" to "the name of |
| a user-defined type"]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered another possible resolution:</p> |
| <blockquote> |
| <p>In light of the resolution to core issue 259, no normative changes |
| in the library clauses are necessary. Add the following non-normative |
| note to the end of 17.4.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a> paragraph 1:</p> |
| <blockquote> |
| [<i>Note:</i> A program may explicitly instantiate standard library |
| templates, even when an explicit instantiation does not depend on |
| a user-defined name. <i>--end note</i>] |
| </blockquote> |
| </blockquote> |
| |
| <p>The LWG rejected this because it was believed that it would make |
| it unnecessarily difficult for library implementors to write |
| high-quality implementations. A program may not include an |
| explicit instantiation of the same template, for the same template |
| arguments, in two different translation units. If users are |
| allowed to provide explicit instantiations of Standard Library |
| templates for built-in types, then library implementors aren't, |
| at least not without nonportable tricks.</p> |
| |
| <p>The most serious problem is a class template that has writeable |
| static member variables. Unfortunately, such class templates are |
| important and, in existing Standard Library implementations, are |
| often explicitly specialized by library implementors: locale facets, |
| which have a writeable static member variable <tt>id</tt>. If a |
| user's explicit instantiation collided with the implementations |
| explicit instantiation, iostream initialization could cause locales |
| to be constructed in an inconsistent state.</p> |
| |
| <p>One proposed implementation technique was for Standard Library |
| implementors to provide explicit instantiations in separate object |
| files, so that they would not be picked up by the linker when the |
| user also provides an explicit instantiation. However, this |
| technique only applies for Standard Library implementations that |
| are packaged as static archives. Most Standard Library |
| implementations nowadays are packaged as dynamic libraries, so this |
| technique would not apply.</p> |
| |
| <p>The Committee is now considering standardization of dynamic |
| linking. If there are such changes in the future, it may be |
| appropriate to revisit this issue later.</p> |
| <hr> |
| <a name="122"><h3>122. streambuf/wstreambuf description should not say they are specializations</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#TC">TC</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998</p> |
| <p>Section 27.5.2 describes the streambuf classes this way: </p> |
| |
| <blockquote> |
| |
| <p>The class streambuf is a specialization of the template class basic_streambuf |
| specialized for the type char. </p> |
| |
| <p>The class wstreambuf is a specialization of the template class basic_streambuf |
| specialized for the type wchar_t. </p> |
| |
| </blockquote> |
| |
| <p>This implies that these classes must be template specializations, not typedefs. </p> |
| |
| <p>It doesn't seem this was intended, since Section 27.5 has them declared as typedefs. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove 27.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf"> [lib.streambuf]</a> paragraphs 2 and 3 (the above two |
| sentences). </p> |
| <p><b>Rationale:</b></p> |
| <p>The <tt>streambuf</tt> synopsis already has a declaration for the |
| typedefs and that is sufficient. </p> |
| <hr> |
| <a name="123"><h3>123. Should valarray helper arrays fill functions be const?</h3></a><p><b>Section:</b> 26.5.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.slice.arr.fill"> [lib.slice.arr.fill]</a>, 26.5.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.gslice.array.fill"> [lib.gslice.array.fill]</a>, 26.5.8.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.mask.array.fill"> [lib.mask.array.fill]</a>, 26.5.9.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.indirect.array.fill"> [lib.indirect.array.fill]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998 </p> |
| <p>One of the operator= in the valarray helper arrays is const and one |
| is not. For example, look at slice_array. This operator= in Section |
| 26.5.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.slice.arr.assign"> [lib.slice.arr.assign]</a> is const: </p> |
| |
| <p> <tt>void operator=(const valarray<T>&) const;</tt> </p> |
| |
| <p>but this one in Section 26.5.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.slice.arr.fill"> [lib.slice.arr.fill]</a> is not: </p> |
| |
| <p> <tt>void operator=(const T&); </tt></p> |
| |
| <p>The description of the semantics for these two functions is similar. </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>26.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.slice.array"> [lib.template.slice.array]</a> Template class slice_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for slice_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.slice.arr.fill"> [lib.slice.arr.fill]</a> slice_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.gslice.array"> [lib.template.gslice.array]</a> Template class gslice_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for gslice_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.gslice.array.fill"> [lib.gslice.array.fill]</a> gslice_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.mask.array"> [lib.template.mask.array]</a> Template class mask_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for mask_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.8.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.mask.array.fill"> [lib.mask.array.fill]</a> mask_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.indirect.array"> [lib.template.indirect.array]</a> Template class indirect_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for indirect_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.9.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.indirect.array.fill"> [lib.indirect.array.fill]</a> indirect_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| |
| <p><i>[Redmond: Robert provided wording.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>There's no good reason for one version of operator= being const and |
| another one not. Because of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#253">253</a>, this now |
| matters: these functions are now callable in more circumstances. In |
| many existing implementations, both versions are already const.</p> |
| <hr> |
| <a name="124"><h3>124. ctype_byname<charT>::do_scan_is & do_scan_not return type should be const charT*</h3></a><p><b>Section:</b> 22.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.ctype.byname"> [lib.locale.ctype.byname]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998</p> |
| <p>In Section 22.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.ctype.byname"> [lib.locale.ctype.byname]</a> |
| ctype_byname<charT>::do_scan_is() and do_scan_not() are declared |
| to return a const char* not a const charT*. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change Section 22.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.ctype.byname"> [lib.locale.ctype.byname]</a> <tt>do_scan_is()</tt> and |
| <tt>do_scan_not()</tt> to return a <tt> const |
| charT*</tt>. </p> |
| <hr> |
| <a name="125"><h3>125. valarray<T>::operator!() return type is inconsistent</h3></a><p><b>Section:</b> 26.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex"> [lib.complex]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998</p> |
| <p>In Section 26.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex"> [lib.complex]</a> valarray<T>::operator!() is |
| declared to return a valarray<T>, but in Section <font color="red">26.3.2.5</font> it is declared to return a valarray<bool>. The |
| latter appears to be correct. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change in Section 26.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex"> [lib.complex]</a> the declaration of |
| <tt>operator!()</tt> so that the return type is |
| <tt>valarray<bool></tt>. </p> |
| <hr> |
| <a name="126"><h3>126. typos in Effects clause of ctype::do_narrow()</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#TC">TC</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998</p> |
| <p>Typos in 22.2.1.1.2 need to be fixed.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In Section 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> change: </p> |
| |
| <pre> do_widen(do_narrow(c),0) == c</pre> |
| |
| <p>to:</p> |
| |
| <pre> do_widen(do_narrow(c,0)) == c</pre> |
| |
| <p>and change:</p> |
| |
| <pre> (is(M,c) || !ctc.is(M, do_narrow(c),dfault) )</pre> |
| |
| <p>to:</p> |
| |
| <pre> (is(M,c) || !ctc.is(M, do_narrow(c,dfault)) )</pre> |
| <hr> |
| <a name="127"><h3>127. auto_ptr<> conversion 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#TC">TC</a> <b>Submitter:</b> Greg Colvin <b>Date:</b> 17 Feb 1999</p> |
| <p>There are two problems with the current <tt>auto_ptr</tt> wording |
| in the standard: </p> |
| |
| <p>First, the <tt>auto_ptr_ref</tt> definition cannot be nested |
| because <tt>auto_ptr<Derived>::auto_ptr_ref</tt> is unrelated to |
| <tt>auto_ptr<Base>::auto_ptr_ref</tt>. <i>Also submitted by |
| Nathan Myers, with the same proposed resolution.</i></p> |
| |
| <p>Second, there is no <tt>auto_ptr</tt> assignment operator taking an |
| <tt>auto_ptr_ref</tt> argument. </p> |
| |
| <p>I have discussed these problems with my proposal coauthor, Bill |
| Gibbons, and with some compiler and library implementors, and we |
| believe that these problems are not desired or desirable implications |
| of the standard. </p> |
| |
| <p>25 Aug 1999: The proposed resolution now reflects changes suggested |
| by Dave Abrahams, with Greg Colvin's concurrence; 1) changed |
| "assignment operator" to "public assignment |
| operator", 2) changed effects to specify use of release(), 3) |
| made the conversion to auto_ptr_ref const. </p> |
| |
| <p>2 Feb 2000: Lisa Lippincott comments: [The resolution of] this issue |
| states that the conversion from auto_ptr to auto_ptr_ref should |
| be const. This is not acceptable, because it would allow |
| initialization and assignment from _any_ const auto_ptr! It also |
| introduces an implementation difficulty in writing this conversion |
| function -- namely, somewhere along the line, a const_cast will be |
| necessary to remove that const so that release() may be called. This |
| may result in undefined behavior [7.1.5.1/4]. The conversion |
| operator does not have to be const, because a non-const implicit |
| object parameter may be bound to an rvalue [13.3.3.1.4/3] |
| [13.3.1/5]. </p> |
| |
| <p>Tokyo: The LWG removed the following from the proposed resolution:</p> |
| |
| <p>In 20.4.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.unary"> [lib.meta.unary]</a>, paragraph 2, and 20.4.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.unary.prop"> [lib.meta.unary.prop]</a>, |
| paragraph 2, make the conversion to auto_ptr_ref const:</p> |
| <blockquote> |
| <pre>template<class Y> operator auto_ptr_ref<Y>() const throw();</pre> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 20.4.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.unary"> [lib.meta.unary]</a>, paragraph 2, move |
| the <tt>auto_ptr_ref</tt> definition to namespace scope.</p> |
| |
| <p>In 20.4.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.unary"> [lib.meta.unary]</a>, paragraph 2, add |
| a public assignment operator to the <tt>auto_ptr</tt> definition: </p> |
| |
| <blockquote> |
| <pre>auto_ptr& operator=(auto_ptr_ref<X> r) throw();</pre> |
| </blockquote> |
| |
| <p>Also add the assignment operator to 20.4.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.unary.prop"> [lib.meta.unary.prop]</a>: </p> |
| |
| <blockquote> |
| <pre>auto_ptr& operator=(auto_ptr_ref<X> r) throw()</pre> |
| |
| <b>Effects:</b> Calls <tt>reset(p.release())</tt> for the <tt>auto_ptr |
| p</tt> that <tt>r</tt> holds a reference to.<br> |
| <b>Returns: </b><tt>*this</tt>. |
| |
| </blockquote> |
| <hr> |
| <a name="129"><h3>129. Need error indication from seekp() and seekg()</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>, 27.6.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.seeks"> [lib.ostream.seeks]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> 22 Feb 1999</p> |
| <p>Currently, the standard does not specify how seekg() and seekp() |
| indicate failure. They are not required to set failbit, and they can't |
| return an error indication because they must return *this, i.e. the |
| stream. Hence, it is undefined what happens if they fail. And they |
| <i>can</i> fail, for instance, when a file stream is disconnected from the |
| underlying file (is_open()==false) or when a wide character file |
| stream must perform a state-dependent code conversion, etc. </p> |
| |
| <p>The stream functions seekg() and seekp() should set failbit in the |
| stream state in case of failure.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to the Effects: clause 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> and to the Effects: clause of seekp() in |
| 27.6.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.seeks"> [lib.ostream.seeks]</a>: </p> |
| |
| <blockquote> |
| <p>In case of failure, the function calls <tt>setstate(failbit)</tt> (which may throw <tt>ios_base::failure</tt>). |
| </p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Setting failbit is the usual error reporting mechanism for streams</p> |
| <hr> |
| <a name="130"><h3>130. Return type of container::erase(iterator) differs for 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>, 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#DR">DR</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 2 Mar 1999</p> |
| <p>Table 67 (23.1.1) says that container::erase(iterator) returns an |
| iterator. Table 69 (23.1.2) says that in addition to this requirement, |
| associative containers also say that container::erase(iterator) |
| returns void. That's not an addition; it's a change to the |
| requirements, which has the effect of making associative containers |
| fail to meet the requirements for containers.</p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| 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 Table 69 Associative container |
| requirements, change the return type of <tt>a.erase(q)</tt> from |
| <tt>void</tt> to <tt>iterator</tt>. Change the |
| assertion/not/pre/post-condition from "erases the element pointed to |
| by <tt>q</tt>" to "erases the element pointed to by <tt>q</tt>. |
| Returns an iterator pointing to the element immediately following q |
| prior to the element being erased. If no such element exists, a.end() |
| is returned." |
| </p> |
| |
| <p> |
| 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 Table 69 Associative container |
| requirements, change the return type of <tt>a.erase(q1, q2)</tt> |
| from <tt>void</tt> to <tt>iterator</tt>. Change the |
| assertion/not/pre/post-condition from "erases the elements in the |
| range <tt>[q1, q2)</tt>" to "erases the elements in the range <tt>[q1, |
| q2)</tt>. Returns q2." |
| </p> |
| |
| <p> |
| In 23.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map"> [lib.map]</a>, in the <tt>map</tt> class synopsis; and |
| in 23.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.multimap"> [lib.multimap]</a>, in the <tt>multimap</tt> class synopsis; and |
| in 23.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.set"> [lib.set]</a>, in the <tt>set</tt> class synopsis; and |
| in 23.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.multiset"> [lib.multiset]</a>, in the <tt>multiset</tt> class synopsis: |
| change the signature of the first <tt>erase</tt> overload to |
| </p> |
| <pre> iterator erase(iterator position); |
| </pre> |
| <p>and change the signature of the third <tt>erase</tt> overload to</p> |
| <pre> iterator erase(iterator first, iterator last); |
| </pre> |
| |
| |
| <p><i>[Pre-Kona: reopened at the request of Howard Hinnant]</i></p> |
| |
| <p><i>[Post-Kona: the LWG agrees the return type should be |
| <tt>iterator</tt>, not <tt>void</tt>. (Alex Stepanov agrees too.) |
| Matt provided wording.]</i></p> |
| |
| <p><i>[ |
| Sydney: the proposed wording went in the right direction, but it |
| wasn't good enough. We want to return an iterator from the range form |
| of erase as well as the single-iterator form. Also, the wording is |
| slightly different from the wording we have for sequences; there's no |
| good reason for having a difference. Matt provided new wording, |
| which we will review at the next meeting. |
| ]</i></p> |
| |
| <hr> |
| <a name="132"><h3>132. list::resize description uses random access iterators</h3></a><p><b>Section:</b> 23.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.capacity"> [lib.deque.capacity]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 6 Mar 1999</p> |
| <p>The description reads:</p> |
| |
| <p>-1- Effects:</p> |
| |
| <pre> if (sz > size()) |
| insert(end(), sz-size(), c); |
| else if (sz < size()) |
| erase(begin()+sz, end()); |
| else |
| ; // do nothing</pre> |
| |
| <p>Obviously list::resize should not be specified in terms of random access iterators.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 23.2.2.2 paragraph 1 to:</p> |
| |
| <p>Effects:</p> |
| |
| <pre> if (sz > size()) |
| insert(end(), sz-size(), c); |
| else if (sz < size()) |
| { |
| iterator i = begin(); |
| advance(i, sz); |
| erase(i, end()); |
| }</pre> |
| |
| <p><i>[Dublin: The LWG asked Howard to discuss exception safety offline |
| with David Abrahams. They had a discussion and believe there is |
| no issue of exception safety with the proposed resolution.]</i></p> |
| <hr> |
| <a name="133"><h3>133. map missing get_allocator()</h3></a><p><b>Section:</b> 23.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map"> [lib.map]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 6 Mar 1999</p> |
| <p>The title says it all.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Insert in 23.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map"> [lib.map]</a>, paragraph 2, |
| after operator= in the map declaration:</p> |
| |
| <pre> allocator_type get_allocator() const;</pre> |
| <hr> |
| <a name="134"><h3>134. vector constructors over specified</h3></a><p><b>Section:</b> 23.2.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.queue"> [lib.queue]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 6 Mar 1999</p> |
| <p>The complexity description says: "It does at most 2N calls to the copy constructor |
| of T and logN reallocations if they are just input iterators ...".</p> |
| |
| <p>This appears to be overly restrictive, dictating the precise memory/performance |
| tradeoff for the implementor.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 23.2.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.queue"> [lib.queue]</a>, paragraph 1 to:</p> |
| |
| <p>-1- Complexity: The constructor template <class |
| InputIterator> vector(InputIterator first, InputIterator last) |
| makes only N calls to the copy constructor of T (where N is the |
| distance between first and last) and no reallocations if iterators |
| first and last are of forward, bidirectional, or random access |
| categories. It makes order N calls to the copy constructor of T and |
| order logN reallocations if they are just input iterators. |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>"at most 2N calls" is correct only if the growth factor |
| is greater than or equal to 2. |
| </p> |
| <hr> |
| <a name="136"><h3>136. seekp, seekg setting wrong streams?</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#WP">WP</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 6 Mar 1999</p> |
| <p>I may be misunderstanding the intent, but should not seekg set only |
| the input stream and seekp set only the output stream? The description |
| seems to say that each should set both input and output streams. If |
| that's really the intent, I withdraw this proposal.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In section 27.6.1.3 change:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(pos_type pos); |
| Effects: If fail() != true, executes rdbuf()->pubseekpos(pos). </pre> |
| |
| <p>To:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(pos_type pos); |
| Effects: If fail() != true, executes rdbuf()->pubseekpos(pos, ios_base::in). </pre> |
| |
| <p>In section 27.6.1.3 change:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(off_type& off, ios_base::seekdir dir); |
| Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir). </pre> |
| |
| <p>To:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(off_type& off, ios_base::seekdir dir); |
| Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir, ios_base::in). </pre> |
| |
| <p>In section 27.6.2.4, paragraph 2 change:</p> |
| |
| <pre>-2- Effects: If fail() != true, executes rdbuf()->pubseekpos(pos). </pre> |
| |
| <p>To:</p> |
| |
| <pre>-2- Effects: If fail() != true, executes rdbuf()->pubseekpos(pos, ios_base::out). </pre> |
| |
| <p>In section 27.6.2.4, paragraph 4 change:</p> |
| |
| <pre>-4- Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir). </pre> |
| |
| <p>To:</p> |
| |
| <pre>-4- Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir, ios_base::out). </pre> |
| |
| <p><i>[Dublin: Dietmar Kühl thinks this is probably correct, but would |
| like the opinion of more iostream experts before taking action.]</i></p> |
| |
| <p><i>[Tokyo: Reviewed by the LWG. PJP noted that although his docs are |
| incorrect, his implementation already implements the Proposed |
| Resolution.]</i></p> |
| |
| <p><i>[Post-Tokyo: Matt Austern comments:<br> |
| Is it a problem with basic_istream and basic_ostream, or is it a problem |
| with basic_stringbuf? |
| We could resolve the issue either by changing basic_istream and |
| basic_ostream, or by changing basic_stringbuf. I prefer the latter |
| change (or maybe both changes): I don't see any reason for the standard to |
| require that std::stringbuf s(std::string("foo"), std::ios_base::in); |
| s.pubseekoff(0, std::ios_base::beg); must fail.<br> |
| This requirement is a bit weird. There's no similar requirement |
| for basic_streambuf<>::seekpos, or for basic_filebuf<>::seekoff or |
| basic_filebuf<>::seekpos.]</i></p> |
| <hr> |
| <a name="137"><h3>137. Do use_facet and has_facet look in the global locale?</h3></a><p><b>Section:</b> 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> 17 Mar 1999</p> |
| <p>Section 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> says:</p> |
| |
| <p>-4- In the call to use_facet<Facet>(loc), the type argument |
| chooses a facet, making available all members of the named type. If |
| Facet is not present in a locale (or, failing that, in the global |
| locale), it throws the standard exception bad_cast. A C++ program can |
| check if a locale implements a particular facet with the template |
| function has_facet<Facet>(). </p> |
| |
| <p>This contradicts the specification given in section |
| 22.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.global.templates"> [lib.locale.global.templates]</a>: |
| <br><br> |
| template <class Facet> const Facet& use_facet(const |
| locale& loc); <br> |
| <br> |
| -1- Get a reference to a facet of a locale. <br> |
| -2- Returns: a reference to the corresponding facet of loc, if present. <br> |
| -3- Throws: bad_cast if has_facet<Facet>(loc) is false. <br> |
| -4- Notes: The reference returned remains valid at least as long as any copy of loc exists |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the phrase "(or, failing that, in the global locale)" |
| from section 22.1.1. </p> |
| <p><b>Rationale:</b></p> |
| <p>Needed for consistency with the way locales are handled elsewhere |
| in the standard.</p> |
| <hr> |
| <a name="139"><h3>139. Optional sequence operation table description unclear</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#TC">TC</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 30 Mar 1999</p> |
| <p>The sentence introducing the Optional sequence operation table |
| (23.1.1 paragraph 12) has two problems:</p> |
| |
| <p>A. It says ``The operations in table 68 are provided only for the containers for which |
| they take constant time.''<br> |
| <br> |
| That could be interpreted in two ways, one of them being ``Even though table 68 shows |
| particular operations as being provided, implementations are free to omit them if they |
| cannot implement them in constant time.''<br> |
| <br> |
| B. That paragraph says nothing about amortized constant time, and it should. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the wording in 23.1.1 paragraph 12 which begins ``The operations in table 68 are provided only..." |
| with:</p> |
| |
| <blockquote> |
| <p>Table 68 lists sequence operations that are provided for some types of sequential |
| containers but not others. An implementation shall provide these operations for all |
| container types shown in the ``container'' column, and shall implement them so as to take |
| amortized constant time.</p> |
| </blockquote> |
| <hr> |
| <a name="141"><h3>141. basic_string::find_last_of, find_last_not_of say pos instead of xpos</h3></a><p><b>Section:</b> 21.3.6.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::find.last.of"> [lib.string::find.last.of]</a>, 21.3.6.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::find.last.not.of"> [lib.string::find.last.not.of]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Arch Robison <b>Date:</b> 28 Apr 1999</p> |
| <p>Sections 21.3.6.4 paragraph 1 and 21.3.6.6 paragraph 1 surely have misprints where they |
| say:<br> |
| <br> |
| — <tt>xpos <= pos</tt> and <tt>pos < size();</tt></p> |
| |
| <p>Surely the document meant to say ``<tt>xpos < size()</tt>'' in both places.</p> |
| |
| <p><i>[Judy Ward also sent in this issue for 21.3.6.4 with the same |
| proposed resolution.]</i></p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change Sections 21.3.6.4 paragraph 1 and 21.3.6.6 paragraph 1, the line which says:<br> |
| <br> |
| — <tt>xpos <= pos</tt> and <tt>pos < size();<br> |
| <br> |
| </tt>to:<br> |
| <tt><br> |
| </tt>— <tt>xpos <= pos</tt> and <tt>xpos < size();</tt></p> |
| <hr> |
| <a name="142"><h3>142. lexicographical_compare complexity wrong</h3></a><p><b>Section:</b> 25.3.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.lex.comparison"> [lib.alg.lex.comparison]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 20 Jun 1999</p> |
| <p>The lexicographical_compare complexity is specified as:<br> |
| <br> |
| "At most min((last1 - first1), (last2 - first2)) |
| applications of the corresponding comparison."<br> |
| <br> |
| The best I can do is twice that expensive.</p> |
| |
| <p>Nicolai Josuttis comments in lib-6862: You mean, to check for |
| equality you have to check both < and >? Yes, IMO you are |
| right! (and Matt states this complexity in his book)</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.3.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.lex.comparison"> [lib.alg.lex.comparison]</a> complexity to:</p> |
| <blockquote> |
| At most <tt>2*min((last1 - first1), (last2 - first2))</tt> |
| applications of the corresponding comparison. |
| </blockquote> |
| |
| <p>Change the example at the end of paragraph 3 to read:</p> |
| <blockquote> |
| [Example:<br> |
| <br> |
| for ( ; first1 != last1 && first2 != last2 ; |
| ++first1, ++first2) {<br> |
| if (*first1 < *first2) return true;<br> |
| if (*first2 < *first1) return false;<br> |
| }<br> |
| return first1 == last1 && first2 != last2;<br> |
| <br> |
| --end example] |
| </blockquote> |
| <hr> |
| <a name="144"><h3>144. Deque constructor complexity wrong </h3></a><p><b>Section:</b> 23.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.array.cons"> [lib.array.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Herb Sutter <b>Date:</b> 9 May 1999</p> |
| <p>In 23.2.1.1 paragraph 6, the deque ctor that takes an iterator range appears |
| to have complexity requirements which are incorrect, and which contradict the |
| complexity requirements for insert(). I suspect that the text in question, |
| below, was taken from vector:</p> |
| <blockquote> |
| <p>Complexity: If the iterators first and last are forward iterators, |
| bidirectional iterators, or random access iterators the constructor makes only |
| N calls to the copy constructor, and performs no reallocations, where N is |
| last - first.</p> |
| </blockquote> |
| <p>The word "reallocations" does not really apply to deque. Further, |
| all of the following appears to be spurious:</p> |
| <blockquote> |
| <p>It makes at most 2N calls to the copy constructor of T and log N |
| reallocations if they are input iterators.1)</p> |
| <p>1) The complexity is greater in the case of input iterators because each |
| element must be added individually: it is impossible to determine the distance |
| between first abd last before doing the copying.</p> |
| </blockquote> |
| <p>This makes perfect sense for vector, but not for deque. Why should deque gain |
| an efficiency advantage from knowing in advance the number of elements to |
| insert?</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.2.1.1 paragraph 6, replace the Complexity description, including the |
| footnote, with the following text (which also corrects the "abd" |
| typo):</p> |
| <blockquote> |
| <p>Complexity: Makes last - first calls to the copy constructor of T.</p> |
| </blockquote> |
| <hr> |
| <a name="146"><h3>146. complex<T> Inserter and Extractor need sentries</h3></a><p><b>Section:</b> 26.3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.ops"> [lib.complex.ops]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> 12 May 1999</p> |
| <p>The <u> extractor</u> for complex numbers is specified as: </p> |
| |
| <blockquote> |
| |
| <p> template<class T, class charT, class traits> <br> |
| basic_istream<charT, traits>& <br> |
| operator>>(basic_istream<charT, traits>& is, complex<T>& x);<br> |
| <br> |
| Effects: Extracts a complex number x of the form: u, (u), or (u,v), |
| where u is the real part and v is the imaginary part |
| (lib.istream.formatted). <br> |
| Requires: The input values be convertible to T. If bad input is |
| encountered, calls is.setstate(ios::failbit) (which may throw |
| ios::failure (lib.iostate.flags). <br> |
| Returns: is .</p> |
| |
| </blockquote> |
| <p>Is it intended that the extractor for complex numbers does not skip |
| whitespace, unlike all other extractors in the standard library do? |
| Shouldn't a sentry be used? <br> |
| <br> |
| The <u>inserter</u> for complex numbers is specified as:</p> |
| |
| <blockquote> |
| |
| <p> template<class T, class charT, class traits> <br> |
| basic_ostream<charT, traits>& <br> |
| operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);<br> |
| <br> |
| Effects: inserts the complex number x onto the stream o as if it were implemented as follows:<br> |
| <br> |
| template<class T, class charT, class traits> <br> |
| basic_ostream<charT, traits>& <br> |
| operator<<(basic_ostream<charT, traits>& o, const complex<T>& x) <br> |
| { <br> |
| basic_ostringstream<charT, traits> s; <br> |
| s.flags(o.flags()); <br> |
| s.imbue(o.getloc()); <br> |
| s.precision(o.precision()); <br> |
| s << '(' << x.real() << "," << x.imag() << ')'; <br> |
| return o << s.str(); <br> |
| }</p> |
| |
| </blockquote> |
| |
| <p>Is it intended that the inserter for complex numbers ignores the |
| field width and does not do any padding? If, with the suggested |
| implementation above, the field width were set in the stream then the |
| opening parentheses would be adjusted, but the rest not, because the |
| field width is reset to zero after each insertion.</p> |
| |
| <p>I think that both operations should use sentries, for sake of |
| consistency with the other inserters and extractors in the |
| library. Regarding the issue of padding in the inserter, I don't know |
| what the intent was. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>After 26.3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex.ops"> [lib.complex.ops]</a> paragraph 14 (operator>>), add a |
| Notes clause:</p> |
| |
| <blockquote> |
| |
| <p>Notes: This extraction is performed as a series of simpler |
| extractions. Therefore, the skipping of whitespace is specified to be the |
| same for each of the simpler extractions.</p> |
| |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>For extractors, the note is added to make it clear that skipping whitespace |
| follows an "all-or-none" rule.</p> |
| |
| <p>For inserters, the LWG believes there is no defect; the standard is correct |
| as written.</p> |
| <hr> |
| <a name="147"><h3>147. Library Intro refers to global functions that aren't global</h3></a><p><b>Section:</b> 17.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.global.functions"> [lib.global.functions]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Lois Goldthwaite <b>Date:</b> 4 Jun 1999</p> |
| <p>The library had many global functions until 17.4.1.1 [lib.contents] |
| paragraph 2 was added: </p> |
| |
| <blockquote> |
| |
| <p>All library entities except macros, operator new and operator |
| delete are defined within the namespace std or namespaces nested |
| within namespace std. </p> |
| |
| </blockquote> |
| |
| <p>It appears "global function" was never updated in the following: </p> |
| |
| <blockquote> |
| |
| <p>17.4.4.3 - Global functions [lib.global.functions]<br> |
| <br> |
| -1- It is unspecified whether any global functions in the C++ Standard |
| Library are defined as inline (dcl.fct.spec).<br> |
| <br> |
| -2- A call to a global function signature described in Clauses |
| lib.language.support through lib.input.output behaves the same as if |
| the implementation declares no additional global function |
| signatures.*<br> |
| <br> |
| [Footnote: A valid C++ program always calls the expected library |
| global function. An implementation may also define additional |
| global functions that would otherwise not be called by a valid C++ |
| program. --- end footnote]<br> |
| <br> |
| -3- A global function cannot be declared by the implementation as |
| taking additional default arguments. <br> |
| <br> |
| 17.4.4.4 - Member functions [lib.member.functions]<br> |
| <br> |
| -2- An implementation can declare additional non-virtual member |
| function signatures within a class: </p> |
| |
| <blockquote> |
| |
| <p>-- by adding arguments with default values to a member function |
| signature; The same latitude does not extend to the implementation of |
| virtual or global functions, however. </p> |
| |
| </blockquote> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> Change "global" to "global or non-member" in:</p> |
| <blockquote> |
| <p>17.4.4.3 [lib.global.functions] section title,<br> |
| 17.4.4.3 [lib.global.functions] para 1,<br> |
| 17.4.4.3 [lib.global.functions] para 2 in 2 places plus 2 |
| places in the footnote,<br> |
| 17.4.4.3 [lib.global.functions] para 3,<br> |
| 17.4.4.4 [lib.member.functions] para 2</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p> |
| Because operator new and delete are global, the proposed resolution |
| was changed from "non-member" to "global or non-member. |
| </p> |
| <hr> |
| <a name="148"><h3>148. Functions in the example facet BoolNames should be const</h3></a><p><b>Section:</b> 22.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facets.examples"> [lib.facets.examples]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Jeremy Siek <b>Date:</b> 3 Jun 1999</p> |
| <p>In 22.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facets.examples"> [lib.facets.examples]</a> paragraph 13, the do_truename() and |
| do_falsename() functions in the example facet BoolNames should be |
| const. The functions they are overriding in |
| numpunct_byname<char> are const. </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facets.examples"> [lib.facets.examples]</a> paragraph 13, insert "const" in |
| two places:</p> |
| <blockquote> |
| <p><tt>string do_truename() const { return "Oui Oui!"; }<br> |
| string do_falsename() const { return "Mais Non!"; }</tt></p> |
| </blockquote> |
| <hr> |
| <a name="150"><h3>150. Find_first_of says integer instead of iterator </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#TC">TC</a> <b>Submitter:</b> Matt McClure <b>Date:</b> 30 Jun 1999</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 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> paragraph 2 from:</p> |
| |
| <blockquote> |
| <p>Returns: The first iterator i in the range [first1, last1) such |
| that for some <u>integer</u> j in the range [first2, last2) ...</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Returns: The first iterator i in the range [first1, last1) such |
| that for some iterator j in the range [first2, last2) ...</p> |
| </blockquote> |
| <hr> |
| <a name="151"><h3>151. Can't currently clear() empty container</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#TC">TC</a> <b>Submitter:</b> Ed Brey <b>Date:</b> 21 Jun 1999</p> |
| <p>For both sequences and associative containers, a.clear() has the |
| semantics of erase(a.begin(),a.end()), which is undefined for an empty |
| container since erase(q1,q2) requires that q1 be dereferenceable |
| (23.1.1,3 and 23.1.2,7). When the container is empty, a.begin() is |
| not dereferenceable.<br> |
| <br> |
| The requirement that q1 be unconditionally dereferenceable causes many |
| operations to be intuitively undefined, of which clearing an empty |
| container is probably the most dire.<br> |
| <br> |
| Since q1 and q2 are only referenced in the range [q1, q2), and [q1, |
| q2) is required to be a valid range, stating that q1 and q2 must be |
| iterators or certain kinds of iterators is unnecessary. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.1.1, paragraph 3, change:</p> |
| <blockquote> |
| <p>p and q2 denote valid iterators to a, q <u> and q1</u> denote valid dereferenceable iterators to a, [q1, q2) denotes a valid range</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>p denotes a valid iterator to a, q denotes a valid dereferenceable iterator to a, [q1, q2) denotes a valid range<u> |
| in a</u></p> |
| </blockquote> |
| <p>In 23.1.2, paragraph 7, change:</p> |
| <blockquote> |
| <p>p and q2 are valid iterators to a, q <u> and q1</u> are valid dereferenceable |
| iterators to a, [q1, q2) is a valid range</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p>p is a valid iterator to a, q is a valid dereferenceable iterator to a, [q1, q2) is a valid range |
| <u>into a</u></p> |
| </blockquote> |
| <hr> |
| <a name="152"><h3>152. Typo in <tt>scan_is()</tt> semantics</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#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The semantics of <tt>scan_is()</tt> (paragraphs 4 and 6) is not exactly described |
| because there is no function <tt>is()</tt> which only takes a character as |
| argument. Also, in the effects clause (paragraph 3), the semantic is also kept |
| vague.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>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> paragraphs 4 and 6, change the returns |
| clause from:</p> |
| <blockquote> |
| <p>"... such that <tt>is(*p)</tt> |
| would..."</p> |
| </blockquote> |
| <p>to: "... such that <tt>is(m, *p)</tt> |
| would...."</p> |
| <hr> |
| <a name="153"><h3>153. Typo in <tt>narrow()</tt> semantics</h3></a><p><b>Section:</b> 22.2.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.ctype.char.members"> [lib.facet.ctype.char.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The description of the array version of <tt>narrow()</tt> (in |
| paragraph 11) is flawed: There is no member <tt>do_narrow()</tt> which |
| takes only three arguments because in addition to the range a default |
| character is needed.</p> |
| |
| <p>Additionally, for both <tt>widen</tt> and <tt>narrow</tt> we have |
| two signatures followed by a <b>Returns</b> clause that only addresses |
| one of them.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the returns clause in 22.2.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.ctype.char.members"> [lib.facet.ctype.char.members]</a> |
| paragraph 10 from:</p> |
| <p> Returns: do_widen(low, high, to).</p> |
| |
| <p>to:</p> |
| <p> Returns: do_widen(c) or do_widen(low, high, to), |
| respectively.</p> |
| |
| <p>Change 22.2.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.ctype.char.members"> [lib.facet.ctype.char.members]</a> paragraph 10 and 11 from:</p> |
| <pre> char narrow(char c, char /*dfault*/) const; |
| const char* narrow(const char* low, const char* high, |
| char /*dfault*/, char* to) const;</pre> |
| <pre> Returns: do_narrow(low, high, to).</pre> |
| <p>to:</p> |
| <pre> char narrow(char c, char dfault) const; |
| const char* narrow(const char* low, const char* high, |
| char dfault, char* to) const;</pre> |
| <pre> Returns: do_narrow(c, dfault) or |
| do_narrow(low, high, dfault, to), respectively.</pre> |
| |
| <p><i>[Kona: 1) the problem occurs in additional places, 2) a user |
| defined version could be different.]</i></p> |
| |
| <p><i>[Post-Tokyo: Dietmar provided the above wording at the request of |
| the LWG. He could find no other places the problem occurred. He |
| asks for clarification of the Kona "a user defined |
| version..." comment above. Perhaps it was a circuitous way of |
| saying "dfault" needed to be uncommented?]</i></p> |
| |
| <p><i>[Post-Toronto: the issues list maintainer has merged in the |
| proposed resolution from issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#207">207</a>, which addresses the |
| same paragraphs.]</i></p> |
| <hr> |
| <a name="154"><h3>154. Missing <tt>double</tt> specifier for <tt>do_get()</tt> |
| </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#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The table in paragraph 7 for the length modifier does not list the length |
| modifier <tt>l</tt> to be applied if the type is <tt>double</tt>. Thus, the |
| standard asks the implementation to do undefined things when using <tt>scanf()</tt> |
| (the missing length modifier for <tt>scanf()</tt> when scanning <tt>double</tt>s |
| is actually a problem I found quite often in production code, too).</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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 7, add a row in the Length |
| Modifier table to say that for <tt>double</tt> a length modifier |
| <tt>l</tt> is to be used.</p> |
| <p><b>Rationale:</b></p> |
| <p>The standard makes an embarrassing beginner's mistake.</p> |
| <hr> |
| <a name="155"><h3>155. Typo in naming the class defining the class <tt>Init</tt> |
| </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#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>There are conflicting statements about where the class |
| <tt>Init</tt> is defined. According to 27.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.objects"> [lib.iostream.objects]</a> paragraph 2 |
| it is defined as <tt>basic_ios::Init</tt>, according to 27.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base"> [lib.ios.base]</a> it is defined as <tt>ios_base::Init</tt>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.objects"> [lib.iostream.objects]</a> paragraph 2 from |
| "<tt>basic_ios::Init"</tt> to |
| "<tt>ios_base::Init"</tt>.</p> |
| <p><b>Rationale:</b></p> |
| <p>Although not strictly wrong, the standard was misleading enough to warrant |
| the change.</p> |
| <hr> |
| <a name="156"><h3>156. Typo in <tt>imbue()</tt> description</h3></a><p><b>Section:</b> 27.4.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.locales"> [lib.ios.base.locales]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>There is a small discrepancy between the declarations of |
| <tt>imbue()</tt>: in 27.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base"> [lib.ios.base]</a> the argument is passed as |
| <tt>locale const&</tt> (correct), in 27.4.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.locales"> [lib.ios.base.locales]</a> it |
| is passed as <tt>locale const</tt> (wrong).</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.4.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.locales"> [lib.ios.base.locales]</a> change the <tt>imbue</tt> argument |
| from "<tt>locale const" to "locale |
| const&".</tt></p> |
| <hr> |
| <a name="158"><h3>158. Underspecified semantics for <tt>setbuf()</tt> |
| </h3></a><p><b>Section:</b> 27.5.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The default behavior of <tt>setbuf()</tt> is described only for the |
| situation that <tt>gptr() != 0 && gptr() != egptr()</tt>: |
| namely to do nothing. What has to be done in other situations |
| is not described although there is actually only one reasonable |
| approach, namely to do nothing, too.</p> |
| |
| <p>Since changing the buffer would almost certainly mess up most |
| buffer management of derived classes unless these classes do it |
| themselves, the default behavior of <tt>setbuf()</tt> should always be |
| to do nothing.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.5.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a>, paragraph 3, Default behavior, |
| to: "Default behavior: Does nothing. Returns this."</p> |
| <hr> |
| <a name="159"><h3>159. Strange use of <tt>underflow()</tt> |
| </h3></a><p><b>Section:</b> 27.5.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.get"> [lib.streambuf.virt.get]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The description of the meaning of the result of |
| <tt>showmanyc()</tt> seems to be rather strange: It uses calls to |
| <tt>underflow()</tt>. Using <tt>underflow()</tt> is strange because |
| this function only reads the current character but does not extract |
| it, <tt>uflow()</tt> would extract the current character. This should |
| be fixed to use <tt>sbumpc()</tt> instead.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.5.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.get"> [lib.streambuf.virt.get]</a> paragraph 1, |
| <tt>showmanyc()</tt>returns clause, by replacing the word |
| "supplied" with the words "extracted from the |
| stream".</p> |
| <hr> |
| <a name="160"><h3>160. Typo: Use of non-existing function <tt>exception()</tt> |
| </h3></a><p><b>Section:</b> 27.6.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream"> [lib.istream]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The paragraph 4 refers to the function <tt>exception()</tt> which |
| is not defined. Probably, the referred function is |
| <tt>basic_ios<>::exceptions()</tt>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream"> [lib.istream]</a>, 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 1, |
| 27.6.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream"> [lib.ostream]</a>, paragraph 3, and 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>, |
| paragraph 1, change "<tt>exception()" to |
| "exceptions()"</tt>.</p> |
| |
| <p><i>[Note to Editor: "exceptions" with an "s" |
| is the correct spelling.]</i></p> |
| <hr> |
| <a name="161"><h3>161. Typo: <tt>istream_iterator</tt> vs. <tt>istreambuf_iterator</tt> |
| </h3></a><p><b>Section:</b> 27.6.1.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.arithmetic"> [lib.istream.formatted.arithmetic]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The note in the second paragraph pretends that the first argument |
| is an object of type <tt>istream_iterator</tt>. This is wrong: It is |
| an object of type <tt>istreambuf_iterator</tt>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.6.1.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.arithmetic"> [lib.istream.formatted.arithmetic]</a> from:</p> |
| <blockquote> |
| <p>The first argument provides an object of the istream_iterator class...</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p>The first argument provides an object of the istreambuf_iterator class...</p> |
| </blockquote> |
| <hr> |
| <a name="164"><h3>164. do_put() has apparently unused fill argument</h3></a><p><b>Section:</b> 22.2.5.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.put.virtuals"> [lib.locale.time.put.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> 23 Jul 1999</p> |
| <p>In 22.2.5.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.put.virtuals"> [lib.locale.time.put.virtuals]</a> the do_put() function is specified |
| as taking a fill character as an argument, but the description of the |
| function does not say whether the character is used at all and, if so, |
| in which way. The same holds for any format control parameters that |
| are accessible through the ios_base& argument, such as the |
| adjustment or the field width. Is strftime() supposed to use the fill |
| character in any way? In any case, the specification of |
| time_put.do_put() looks inconsistent to me.<br> <br> Is the |
| signature of do_put() wrong, or is the effects clause incomplete?</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following note after 22.2.5.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.put.virtuals"> [lib.locale.time.put.virtuals]</a> |
| paragraph 2:</p> |
| <blockquote> |
| <p> [Note: the <tt>fill</tt> argument may be used in the implementation-defined formats, or by derivations. A space character is a reasonable default |
| for this argument. --end Note]</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The LWG felt that while the normative text was correct, |
| users need some guidance on what to pass for the <tt>fill</tt> |
| argument since the standard doesn't say how it's used.</p> |
| <hr> |
| <a name="165"><h3>165. <tt>xsputn()</tt>, <tt>pubsync()</tt> never called by <tt>basic_ostream</tt> members?</h3></a><p><b>Section:</b> 27.6.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream"> [lib.ostream]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>Paragraph 2 explicitly states that none of the <tt>basic_ostream</tt> |
| functions falling into one of the groups "formatted output functions" |
| and "unformatted output functions" calls any stream buffer function |
| which might call a virtual function other than <tt>overflow()</tt>. Basically |
| this is fine but this implies that <tt>sputn()</tt> (this function would call |
| the virtual function <tt>xsputn()</tt>) is never called by any of the standard |
| output functions. Is this really intended? At minimum it would be convenient to |
| call <tt>xsputn()</tt> for strings... Also, the statement that <tt>overflow()</tt> |
| is the only virtual member of <tt>basic_streambuf</tt> called is in conflict |
| with the definition of <tt>flush()</tt> which calls <tt>rdbuf()->pubsync()</tt> |
| and thereby the virtual function <tt>sync()</tt> (<tt>flush()</tt> is listed |
| under "unformatted output functions").</p> |
| <p>In addition, I guess that the sentence starting with "They may use other |
| public members of <tt>basic_ostream</tt> ..." probably was intended to |
| start with "They may use other public members of <tt>basic_streamuf</tt>..." |
| although the problem with the virtual members exists in both cases.</p> |
| <p>I see two obvious resolutions:</p> |
| <ol> |
| <li>state in a footnote that this means that <tt>xsputn()</tt> will never be |
| called by any ostream member and that this is intended.</li> |
| <li>relax the restriction and allow calling <tt>overflow()</tt> and <tt>xsputn()</tt>. |
| Of course, the problem with <tt>flush()</tt> has to be resolved in some way.</li> |
| </ol> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the last sentence of 27.6.2.1 (lib.ostream) paragraph 2 from:</p> |
| <blockquote> |
| <p>They may use other public members of basic_ostream except that they do not |
| invoke any virtual members of rdbuf() except overflow().</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>They may use other public members of basic_ostream except that they shall |
| not invoke any virtual members of rdbuf() except overflow(), xsputn(), and |
| sync().</p> |
| </blockquote> |
| |
| <p><i>[Kona: the LWG believes this is a problem. Wish to ask Jerry or |
| PJP why the standard is written this way.]</i></p> |
| |
| <p><i>[Post-Tokyo: Dietmar supplied wording at the request of the |
| LWG. He comments: The rules can be made a little bit more specific if |
| necessary be explicitly spelling out what virtuals are allowed to be |
| called from what functions and eg to state specifically that flush() |
| is allowed to call sync() while other functions are not.]</i></p> |
| <hr> |
| <a name="167"><h3>167. Improper use of <tt>traits_type::length()</tt> |
| </h3></a><p><b>Section:</b> 27.6.2.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>Paragraph 4 states that the length is determined using |
| <tt>traits::length(s)</tt>. Unfortunately, this function is not |
| defined for example if the character type is <tt>wchar_t</tt> and the |
| type of <tt>s</tt> is <tt>char const*</tt>. Similar problems exist if |
| the character type is <tt>char</tt> and the type of <tt>s</tt> is |
| either <tt>signed char const*</tt> or <tt>unsigned char |
| const*</tt>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.6.2.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a> paragraph 4 from:</p> |
| <blockquote> |
| <p>Effects: Behaves like an formatted inserter (as described in |
| lib.ostream.formatted.reqmts) of out. After a sentry object is |
| constructed it inserts characters. The number of characters starting |
| at s to be inserted is traits::length(s). Padding is determined as |
| described in lib.facet.num.put.virtuals. The traits::length(s) |
| characters starting at s are widened using out.widen |
| (lib.basic.ios.members). The widened characters and any required |
| padding are inserted into out. Calls width(0).</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Effects: Behaves like a formatted inserter (as described in |
| lib.ostream.formatted.reqmts) of out. After a sentry object is |
| constructed it inserts <i>n</i> characters starting at <i>s</i>, |
| where <i>n</i> is the number that would be computed as if by:</p> |
| <ul> |
| <li>traits::length(s) for the overload where the first argument is of |
| type basic_ostream<charT, traits>& and the second is |
| of type const charT*, and also for the overload where the first |
| argument is of type basic_ostream<char, traits>& and |
| the second is of type const char*.</li> |
| <li>std::char_traits<char>::length(s) |
| for the overload where the first argument is of type |
| basic_ostream<charT, traits>& and the second is of type |
| const char*.</li> |
| <li>traits::length(reinterpret_cast<const char*>(s)) |
| for the other two overloads.</li> |
| </ul> |
| <p>Padding is determined as described in |
| lib.facet.num.put.virtuals. The <i>n</i> characters starting at |
| <i>s</i> are widened using out.widen (lib.basic.ios.members). The |
| widened characters and any required padding are inserted into |
| out. Calls width(0).</p> |
| </blockquote> |
| |
| <p><i>[Santa Cruz: Matt supplied new wording]</i></p> |
| |
| <p><i>[Kona: changed "where <i>n</i> is" to " where <i>n</i> is the |
| number that would be computed as if by"]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>We have five separate cases. In two of them we can use the |
| user-supplied traits class without any fuss. In the other three we |
| try to use something as close to that user-supplied class as possible. |
| In two cases we've got a traits class that's appropriate for |
| char and what we've got is a const signed char* or a const |
| unsigned char*; that's close enough so we can just use a reinterpret |
| cast, and continue to use the user-supplied traits class. Finally, |
| there's one case where we just have to give up: where we've got a |
| traits class for some arbitrary charT type, and we somehow have to |
| deal with a const char*. There's nothing better to do but fall back |
| to char_traits<char></p> |
| <hr> |
| <a name="168"><h3>168. Typo: formatted vs. unformatted</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#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The first paragraph begins with a descriptions what has to be done |
| in <i>formatted</i> output functions. Probably this is a typo and the |
| paragraph really want to describe unformatted output functions...</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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> paragraph 1, the first and last |
| sentences, change the word "formatted" to |
| "unformatted":</p> |
| <blockquote> |
| <p>"Each <b>unformatted </b> output function begins ..."<br> |
| "... value specified for the <b>unformatted </b> output |
| function."</p> |
| </blockquote> |
| <hr> |
| <a name="169"><h3>169. Bad efficiency of <tt>overflow()</tt> mandated</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#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>Paragraph 8, Notes, of this section seems to mandate an extremely |
| inefficient way of buffer handling for <tt>basic_stringbuf</tt>, |
| especially in view of the restriction that <tt>basic_ostream</tt> |
| member functions are not allowed to use <tt>xsputn()</tt> (see 27.6.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream"> [lib.ostream]</a>): For each character to be inserted, a new buffer |
| is to be created.</p> |
| <p>Of course, the resolution below requires some handling of |
| simultaneous input and output since it is no longer possible to update |
| <tt>egptr()</tt> whenever <tt>epptr()</tt> is changed. A possible |
| solution is to handle this in <tt>underflow()</tt>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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> paragraph 8, Notes, insert the words |
| "at least" as in the following:</p> |
| <blockquote> |
| <p>To make a write position available, the function reallocates (or initially |
| allocates) an array object with a sufficient number of elements to hold the |
| current array object (if any), plus <b>at least</b> one additional write |
| position.</p> |
| </blockquote> |
| <hr> |
| <a name="170"><h3>170. Inconsistent definition of <tt>traits_type</tt> |
| </h3></a><p><b>Section:</b> 27.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringstream"> [lib.stringstream]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>The classes <tt>basic_stringstream</tt> (27.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringstream"> [lib.stringstream]</a>), |
| <tt>basic_istringstream</tt> (27.7.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istringstream"> [lib.istringstream]</a>), and |
| <tt>basic_ostringstream</tt> (27.7.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostringstream"> [lib.ostringstream]</a>) are inconsistent |
| in their definition of the type <tt>traits_type</tt>: For |
| <tt>istringstream</tt>, this type is defined, for the other two it is |
| not. This should be consistent.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p><b>Proposed resolution:</b></p> <p>To the declarations of |
| <tt>basic_ostringstream</tt> (27.7.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostringstream"> [lib.ostringstream]</a>) and |
| <tt>basic_stringstream</tt> (27.7.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringstream"> [lib.stringstream]</a>) add:</p> |
| <blockquote> |
| <pre>typedef traits traits_type;</pre> |
| </blockquote> |
| <hr> |
| <a name="171"><h3>171. Strange <tt>seekpos()</tt> semantics due to joint position</h3></a><p><b>Section:</b> 27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p> |
| <p>Overridden virtual functions, seekpos()</p> <p>In 27.8.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf"> [lib.filebuf]</a> paragraph 3, it is stated that a joint input and |
| output position is maintained by <tt>basic_filebuf</tt>. Still, the |
| description of <tt>seekpos()</tt> seems to talk about different file |
| positions. In particular, it is unclear (at least to me) what is |
| supposed to happen to the output buffer (if there is one) if only the |
| input position is changed. The standard seems to mandate that the |
| output buffer is kept and processed as if there was no positioning of |
| the output position (by changing the input position). Of course, this |
| can be exactly what you want if the flag <tt>ios_base::ate</tt> is |
| set. However, I think, the standard should say something like |
| this:</p> |
| <ul> |
| <li>If <tt>(which & mode) == 0</tt> neither read nor write position is |
| changed and the call fails. Otherwise, the joint read and write position is |
| altered to correspond to <tt>sp</tt>.</li> |
| <li>If there is an output buffer, the output sequences is updated and any |
| unshift sequence is written before the position is altered.</li> |
| <li>If there is an input buffer, the input sequence is updated after the |
| position is altered.</li> |
| </ul> |
| <p>Plus the appropriate error handling, that is...</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the unnumbered paragraph in 27.8.1.4 (lib.filebuf.virtuals) before |
| paragraph 14 from:</p> |
| <blockquote> |
| <p>pos_type seekpos(pos_type sp, ios_base::openmode = ios_base::in | |
| ios_base::out);</p> |
| <p>Alters the file position, if possible, to correspond to the position stored |
| in sp (as described below).</p> |
| <p>- if (which&ios_base::in)!=0, set the file position to sp, then update |
| the input sequence</p> |
| <p>- if (which&ios_base::out)!=0, then update the output sequence, write |
| any unshift sequence, and set the file position to sp.</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>pos_type seekpos(pos_type sp, ios_base::openmode = ios_base::in | |
| ios_base::out);</p> |
| <p>Alters the file position, if possible, to correspond to the position stored |
| in sp (as described below). Altering the file position performs as follows:</p> |
| <p>1. if (om & ios_base::out)!=0, then update the output sequence and |
| write any unshift sequence;</p> |
| <p>2. set the file position to sp;</p> |
| <p>3. if (om & ios_base::in)!=0, then update the input sequence;</p> |
| <p>where om is the open mode passed to the last call to open(). The operation |
| fails if is_open() returns false.</p> |
| </blockquote> |
| |
| <p><i>[Kona: Dietmar is working on a proposed resolution.]</i></p> |
| <p><i>[Post-Tokyo: Dietmar supplied the above wording.]</i></p> |
| <hr> |
| <a name="172"><h3>172. Inconsistent types for <tt>basic_istream::ignore()</tt> |
| </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#TC">TC</a> <b>Submitter:</b> Greg Comeau, Dietmar Kühl <b>Date:</b> 23 Jul 1999</p> |
| <p>In 27.6.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream"> [lib.istream]</a> the function |
| <tt>ignore()</tt> gets an object of type <tt>streamsize</tt> as first |
| argument. However, 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 23 the first argument is of type <tt>int.</tt></p> |
| |
| <p>As far as I can see this is not really a contradiction because |
| everything is consistent if <tt>streamsize</tt> is typedef to be |
| <tt>int</tt>. However, this is almost certainly not what was |
| intended. The same thing happened to <tt>basic_filebuf::setbuf()</tt>, |
| as described in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#173">173</a>.</p> |
| |
| <p>Darin Adler also |
| submitted this issue, commenting: Either 27.6.1.1 should be modified |
| to show a first parameter of type int, or 27.6.1.3 should be modified |
| to show a first parameter of type streamsize and use |
| numeric_limits<streamsize>::max.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>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 23 and 24, change both uses |
| of <tt>int</tt> in the description of <tt>ignore()</tt> to |
| <tt>streamsize</tt>.</p> |
| <hr> |
| <a name="173"><h3>173. Inconsistent types for <tt>basic_filebuf::setbuf()</tt> |
| </h3></a><p><b>Section:</b> 27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Greg Comeau, Dietmar Kühl <b>Date:</b> 23 Jul 1999</p> |
| |
| <p> |
| In 27.8.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf"> [lib.filebuf]</a> the function <tt>setbuf()</tt> gets an |
| object of type <tt>streamsize</tt> as second argument. However, in |
| 27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a> paragraph 9 the second argument is of type |
| <tt>int</tt>. |
| </p> |
| |
| <p> |
| As far as I can see this is not really a contradiction because |
| everything is consistent if <tt>streamsize</tt> is typedef to be |
| <tt>int</tt>. However, this is almost certainly not what was |
| intended. The same thing happened to <tt>basic_istream::ignore()</tt>, |
| as described in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#172">172</a>. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.8.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.filebuf.virtuals"> [lib.filebuf.virtuals]</a> paragraph 9, change all uses of |
| <tt>int</tt> in the description of <tt>setbuf()</tt> to |
| <tt>streamsize</tt>.</p> |
| <hr> |
| <a name="174"><h3>174. Typo: <tt>OFF_T</tt> vs. <tt>POS_T</tt> |
| </h3></a><p><b>Section:</b> D.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.ios.members"> [depr.ios.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 23 Jul 1999</p> |
| <p>According to paragraph 1 of this section, <tt>streampos</tt> is the |
| type <tt>OFF_T</tt>, the same type as <tt>streamoff</tt>. However, in |
| paragraph 6 the <tt>streampos</tt> gets the type <tt>POS_T</tt></p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change D.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.ios.members"> [depr.ios.members]</a> paragraph 1 from "<tt>typedef |
| OFF_T streampos;</tt>" to "<tt>typedef POS_T |
| streampos;</tt>"</p> |
| <hr> |
| <a name="175"><h3>175. Ambiguity for <tt>basic_streambuf::pubseekpos()</tt> and a few other functions.</h3></a><p><b>Section:</b> D.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.ios.members"> [depr.ios.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 23 Jul 1999</p> |
| <p>According to paragraph 8 of this section, the methods |
| <tt>basic_streambuf::pubseekpos()</tt>, |
| <tt>basic_ifstream::open()</tt>, and <tt>basic_ofstream::open</tt> |
| "may" be overloaded by a version of this function taking the |
| type <tt>ios_base::open_mode</tt> as last argument argument instead of |
| <tt>ios_base::openmode</tt> (<tt>ios_base::open_mode</tt> is defined |
| in this section to be an alias for one of the integral types). The |
| clause specifies, that the last argument has a default argument in |
| three cases. However, this generates an ambiguity with the overloaded |
| version because now the arguments are absolutely identical if the last |
| argument is not specified.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In D.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.ios.members"> [depr.ios.members]</a> paragraph 8, remove the default arguments for |
| <tt>basic_streambuf::pubseekpos()</tt>, |
| <tt>basic_ifstream::open()</tt>, and |
| <tt>basic_ofstream::open().</tt></p> |
| <hr> |
| <a name="176"><h3>176. <tt>exceptions()</tt> in <tt>ios_base</tt>...?</h3></a><p><b>Section:</b> D.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.ios.members"> [depr.ios.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 23 Jul 1999</p> |
| <p>The "overload" for the function <tt>exceptions()</tt> in |
| paragraph 8 gives the impression that there is another function of |
| this function defined in class <tt>ios_base</tt>. However, this is not |
| the case. Thus, it is hard to tell how the semantics (paragraph 9) can |
| be implemented: "Call the corresponding member function specified |
| in clause 27 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.input.output"> [lib.input.output]</a>."</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In D.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.ios.members"> [depr.ios.members]</a> paragraph 8, move the declaration of the |
| function <tt>exceptions()</tt>into class <tt>basic_ios</tt>.</p> |
| <hr> |
| <a name="179"><h3>179. Comparison of const_iterators to iterators doesn't work</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#WP">WP</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 2 Jul 1998</p> |
| <p>Currently the following will not compile on two well-known standard |
| library implementations:</p> |
| |
| <blockquote> |
| <pre>#include <set> |
| using namespace std; |
| |
| void f(const set<int> &s) |
| { |
| set<int>::iterator i; |
| if (i==s.end()); // s.end() returns a const_iterator |
| }</pre> |
| </blockquote> |
| |
| <p> |
| The reason this doesn't compile is because operator== was implemented |
| as a member function of the nested classes set:iterator and |
| set::const_iterator, and there is no conversion from const_iterator to |
| iterator. Surprisingly, (s.end() == i) does work, though, because of |
| the conversion from iterator to const_iterator. |
| </p> |
| |
| <p> |
| I don't see a requirement anywhere in the standard that this must |
| work. Should there be one? If so, I think the requirement would need |
| to be added to the tables in section 24.1.1. I'm not sure about the |
| wording. If this requirement existed in the standard, I would think |
| that implementors would have to make the comparison operators |
| non-member functions.</p> |
| |
| <p>This issues was also raised on comp.std.c++ by Darin |
| Adler. The example given was:</p> |
| |
| <blockquote> |
| <pre>bool check_equal(std::deque<int>::iterator i, |
| std::deque<int>::const_iterator ci) |
| { |
| return i == ci; |
| }</pre> |
| </blockquote> |
| |
| <p>Comment from John Potter:</p> |
| <blockquote> |
| <p> |
| In case nobody has noticed, accepting it will break reverse_iterator. |
| </p> |
| |
| <p> |
| The fix is to make the comparison operators templated on two types. |
| </p> |
| |
| <pre> template <class Iterator1, class Iterator2> |
| bool operator== (reverse_iterator<Iterator1> const& x, |
| reverse_iterator<Iterator2> const& y); |
| </pre> |
| |
| <p> |
| Obviously: return x.base() == y.base(); |
| </p> |
| |
| <p> |
| Currently, no reverse_iterator to const_reverse_iterator compares are |
| valid. |
| </p> |
| |
| <p> |
| BTW, I think the issue is in support of bad code. Compares should be |
| between two iterators of the same type. All std::algorithms require |
| the begin and end iterators to be of the same type. |
| </p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Insert this paragraph after 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> paragraph 7:</p> |
| <blockquote> |
| <p>In the expressions</p> |
| <pre> i == j |
| i != j |
| i < j |
| i <= j |
| i >= j |
| i > j |
| i - j |
| </pre> |
| <p>Where i and j denote objects of a container's iterator type, |
| either or both may be replaced by an object of the container's |
| const_iterator type referring to the same element with no |
| change in semantics.</p> |
| </blockquote> |
| |
| <p><i>[post-Toronto: Judy supplied a proposed resolution saying that |
| <tt>iterator</tt> and <tt>const_iterator</tt> could be freely mixed in |
| iterator comparison and difference operations.]</i></p> |
| |
| <p><i>[Redmond: Dave and Howard supplied a new proposed resolution which |
| explicitly listed expressions; there was concern that the previous |
| proposed resolution was too informal.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p> |
| The LWG believes it is clear that the above wording applies only to |
| the nested types <tt>X::iterator</tt> and <tt>X::const_iterator</tt>, |
| where <tt>X</tt> is a container. There is no requirement that |
| <tt>X::reverse_iterator</tt> and <tt>X::const_reverse_iterator</tt> |
| can be mixed. If mixing them is considered important, that's a |
| separate issue. (Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280">280</a>.) |
| </p> |
| <hr> |
| <a name="181"><h3>181. make_pair() unintended behavior</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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 3 Aug 1999</p> |
| <p>The claim has surfaced in Usenet that expressions such as<br> |
| <br> |
| <tt>make_pair("abc", 3)</tt><br> |
| <br> |
| are illegal, notwithstanding their use in examples, because template instantiation tries to bind the first template |
| parameter to <tt> const char (&)[4]</tt>, which type is uncopyable.<br> |
| <br> |
| I doubt anyone intended that behavior... |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 20.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.utility"> [lib.utility]</a>, paragraph 1 change the following |
| declaration of make_pair():</p> |
| <blockquote> |
| <pre>template <class T1, class T2> pair<T1,T2> make_pair(const T1&, const T2&);</pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <pre>template <class T1, class T2> pair<T1,T2> make_pair(T1, T2);</pre> |
| </blockquote> |
| <p> In 20.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.pairs"> [lib.pairs]</a> paragraph 7 and the line before, change:</p> |
| <blockquote> |
| <pre>template <class T1, class T2> |
| pair<T1, T2> make_pair(const T1& x, const T2& y);</pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <pre>template <class T1, class T2> |
| pair<T1, T2> make_pair(T1 x, T2 y);</pre> |
| </blockquote> |
| <p>and add the following footnote to the effects clause:</p> |
| <blockquote> |
| <p> According to 12.8 [class.copy], an implementation is permitted |
| to not perform a copy of an argument, thus avoiding unnecessary |
| copies.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Two potential fixes were suggested by Matt Austern and Dietmar |
| Kühl, respectively, 1) overloading with array arguments, and 2) use of |
| a reference_traits class with a specialization for arrays. Andy |
| Koenig suggested changing to pass by value. In discussion, it appeared |
| that this was a much smaller change to the standard that the other two |
| suggestions, and any efficiency concerns were more than offset by the |
| advantages of the solution. Two implementors reported that the |
| proposed resolution passed their test suites.</p> |
| <hr> |
| <a name="182"><h3>182. Ambiguous references to size_t</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#WP">WP</a> <b>Submitter:</b> Al Stevens <b>Date:</b> 15 Aug 1999</p> |
| <p>Many references to <tt> size_t</tt> throughout the document |
| omit the <tt> std::</tt> namespace qualification.</p> <p>For |
| example, 17.4.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.replacement.functions"> [lib.replacement.functions]</a> paragraph 2:</p> |
| <blockquote> |
| <pre>— operator new(size_t) |
| — operator new(size_t, const std::nothrow_t&) |
| — operator new[](size_t) |
| — operator new[](size_t, const std::nothrow_t&)</pre> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> In 17.4.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.replacement.functions"> [lib.replacement.functions]</a> paragraph 2: replace:</p> |
| <blockquote> |
| <p><tt> - operator new(size_t)<br> |
| - operator new(size_t, const std::nothrow_t&)<br> |
| - operator new[](size_t)<br> |
| - operator new[](size_t, const std::nothrow_t&)</tt></p> |
| </blockquote> |
| <p> by:</p> |
| <blockquote> |
| <pre>- operator new(std::size_t) |
| - operator new(std::size_t, const std::nothrow_t&) |
| - operator new[](std::size_t) |
| - operator new[](std::size_t, const std::nothrow_t&)</pre> |
| </blockquote> |
| <p>In [lib.allocator.requirements] 20.1.5, paragraph 4: replace:</p> |
| <blockquote> |
| <p>The typedef members pointer, const_pointer, size_type, and difference_type |
| are required to be T*, T const*, size_t, and ptrdiff_t, respectively.</p> |
| </blockquote> |
| <p> by:</p> |
| <blockquote> |
| <p>The typedef members pointer, const_pointer, size_type, and difference_type |
| are required to be T*, T const*, std::size_t, and std::ptrdiff_t, |
| respectively.</p> |
| </blockquote> |
| <p>In [lib.allocator.members] 20.4.1.1, paragraphs 3 and 6: replace:</p> |
| <blockquote> |
| <p>3 Notes: Uses ::operator new(size_t) (18.4.1).</p> |
| <p>6 Note: the storage is obtained by calling ::operator new(size_t), but it |
| is unspecified when or how often this function is called. The use of hint is |
| unspecified, but intended as an aid to locality if an implementation so |
| desires.</p> |
| </blockquote> |
| <p>by:</p> |
| <blockquote> |
| <p>3 Notes: Uses ::operator new(std::size_t) (18.4.1).</p> |
| <p>6 Note: the storage is obtained by calling ::operator new(std::size_t), but |
| it is unspecified when or how often this function is called. The use of hint |
| is unspecified, but intended as an aid to locality if an implementation so |
| desires.</p> |
| </blockquote> |
| <p>In [lib.char.traits.require] 21.1.1, paragraph 1: replace:</p> |
| <blockquote> |
| <p>In Table 37, X denotes a Traits class defining types and functions for the |
| character container type CharT; c and d denote values of type CharT; p and q |
| denote values of type const CharT*; s denotes a value of type CharT*; n, i and |
| j denote values of type size_t; e and f denote values of type X::int_type; pos |
| denotes a value of type X::pos_type; and state denotes a value of type X::state_type.</p> |
| </blockquote> |
| <p>by:</p> |
| <blockquote> |
| <p>In Table 37, X denotes a Traits class defining types and functions for the |
| character container type CharT; c and d denote values of type CharT; p and q |
| denote values of type const CharT*; s denotes a value of type CharT*; n, i and |
| j denote values of type std::size_t; e and f denote values of type X::int_type; |
| pos denotes a value of type X::pos_type; and state denotes a value of type X::state_type.</p> |
| </blockquote> |
| <p>In [lib.char.traits.require] 21.1.1, table 37: replace the return type of |
| X::length(p): "size_t" by "std::size_t".</p> |
| <p> In [lib.std.iterator.tags] 24.3.3, paragraph 2: replace:<br> |
| typedef ptrdiff_t difference_type;<br> |
| by:<br> |
| typedef std::ptrdiff_t difference_type;</p> |
| <p> In [lib.locale.ctype] 22.2.1.1 put namespace std { ...} around the |
| declaration of template <class charT> class ctype.<br> |
| <br> |
| In [lib.iterator.traits] 24.3.1, paragraph 2 put namespace std { ...} around the declaration of:<br> |
| <br> |
| template<class Iterator> struct iterator_traits<br> |
| template<class T> struct iterator_traits<T*><br> |
| template<class T> struct iterator_traits<const T*></p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes correcting names like <tt>size_t</tt> and |
| <tt>ptrdiff_t</tt> to <tt>std::size_t</tt> and <tt>std::ptrdiff_t</tt> |
| to be essentially editorial. There there can't be another size_t or |
| ptrdiff_t meant anyway because, according to 17.4.3.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.extern.types"> [lib.extern.types]</a>,</p> |
| |
| <blockquote> |
| For each type T from the Standard C library, the types ::T and std::T |
| are reserved to the implementation and, when defined, ::T shall be |
| identical to std::T. |
| </blockquote> |
| |
| <p>The issue is treated as a Defect Report to make explicit the Project |
| Editor's authority to make this change.</p> |
| |
| <p><i>[Post-Tokyo: Nico Josuttis provided the above wording at the |
| request of the LWG.]</i></p> |
| |
| <p><i>[Toronto: This is tangentially related to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a>, but only tangentially: the intent of this issue is to |
| address use of the name <tt>size_t</tt> in contexts outside of |
| namespace std, such as in the description of <tt>::operator new</tt>. |
| The proposed changes should be reviewed to make sure they are |
| correct.]</i></p> |
| |
| <p><i>[pre-Copenhagen: Nico has reviewed the changes and believes |
| them to be correct.]</i></p> |
| |
| <hr> |
| <a name="183"><h3>183. I/O stream manipulators don't work for wide character streams</h3></a><p><b>Section:</b> 27.6.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.std.manip"> [lib.std.manip]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 7 Jul 1999</p> |
| <p>27.6.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.std.manip"> [lib.std.manip]</a> paragraph 3 says (clause numbering added for |
| exposition):</p> |
| <blockquote> |
| <p>Returns: An object s of unspecified type such that if [1] out is an (instance |
| of) basic_ostream then the expression out<<s behaves as if f(s) were |
| called, and if [2] in is an (instance of) basic_istream then the expression |
| in>>s behaves as if f(s) were called. Where f can be defined as: ios_base& |
| f(ios_base& str, ios_base::fmtflags mask) { // reset specified flags |
| str.setf(ios_base::fmtflags(0), mask); return str; } [3] The expression |
| out<<s has type ostream& and value out. [4] The expression in>>s |
| has type istream& and value in.</p> |
| </blockquote> |
| <p>Given the definitions [1] and [2] for out and in, surely [3] should read: |
| "The expression out << s has type basic_ostream& ..." and |
| [4] should read: "The expression in >> s has type basic_istream& |
| ..."</p> |
| <p>If the wording in the standard is correct, I can see no way of implementing |
| any of the manipulators so that they will work with wide character streams.</p> |
| <p>e.g. wcout << setbase( 16 );</p> |
| <p>Must have value 'wcout' (which makes sense) and type 'ostream&' (which |
| doesn't).</p> |
| <p>The same "cut'n'paste" type also seems to occur in Paras 4,5,7 and |
| 8. In addition, Para 6 [setfill] has a similar error, but relates only to |
| ostreams.</p> |
| <p>I'd be happier if there was a better way of saying this, to make it clear |
| that the value of the expression is "the same specialization of |
| basic_ostream as out"&</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace section 27.6.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.std.manip"> [lib.std.manip]</a> except paragraph 1 with the |
| following:</p> |
| <blockquote> |
| <p>2- The type designated smanip in each of the following function |
| descriptions is implementation-specified and may be different for each |
| function.<br> |
| <br> |
| <tt>smanip resetiosflags(ios_base::fmtflags mask);</tt><br> |
| <br> |
| -3- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, mask) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if |
| f(s, mask) were called. The function f can be defined as:*<br> |
| <br> |
| [Footnote: The expression cin >> resetiosflags(ios_base::skipws) |
| clears ios_base::skipws in the format flags stored in the |
| basic_istream<charT,traits> object cin (the same as cin >> |
| noskipws), and the expression cout << |
| resetiosflags(ios_base::showbase) clears |
| ios_base::showbase in the format flags stored in the |
| basic_ostream<charT,traits> object cout (the same as cout |
| << |
| noshowbase). --- end footnote]<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, ios_base::fmtflags mask)<br> |
| {<br> |
| // reset specified flags<br> |
| str.setf(ios_base::fmtflags(0), mask);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in.<br> |
| <br> |
| <tt>smanip setiosflags(ios_base::fmtflags mask);</tt><br> |
| <br> |
| -4- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, mask) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, |
| mask) were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, ios_base::fmtflags mask)<br> |
| {<br> |
| // set specified flags<br> |
| str.setf(mask);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in.<br> |
| <br> |
| <tt>smanip setbase(int base);</tt><br> |
| <br> |
| -5- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, base) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, |
| base) were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, int base)<br> |
| {<br> |
| // set basefield<br> |
| str.setf(base == 8 ? ios_base::oct :<br> |
| base == 10 ? ios_base::dec :<br> |
| base == 16 ? ios_base::hex :<br> |
| ios_base::fmtflags(0), ios_base::basefield);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in.<br> |
| <br> |
| <tt>smanip setfill(char_type c);<br> |
| </tt><br> |
| -6- Returns: An object s of unspecified type such that if out is (or is |
| derived from) basic_ostream<charT,traits> and c has type charT |
| then the |
| expression out<<s behaves as if f(s, c) were called. The function |
| f can be |
| defined as:<br> |
| <br> |
| <tt>template<class charT, class traits><br> |
| basic_ios<charT,traits>& f(basic_ios<charT,traits>& str, charT c)<br> |
| {<br> |
| // set fill character<br> |
| str.fill(c);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out.<br> |
| <br> |
| <tt>smanip setprecision(int n);</tt><br> |
| <br> |
| -7- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, n) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, n) |
| were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, int n)<br> |
| {<br> |
| // set precision<br> |
| str.precision(n);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in<br> |
| .<br> |
| <tt>smanip setw(int n);<br> |
| </tt><br> |
| -8- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, n) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, n) |
| were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, int n)<br> |
| {<br> |
| // set width<br> |
| str.width(n);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type |
| basic_ostream<charT,traits>& and value out. The expression |
| in>>s has type basic_istream<charT,traits>& and value |
| in. |
| </p> |
| </blockquote> |
| |
| <p><i>[Kona: Andy Sawyer and Beman Dawes will work to improve the wording of |
| the proposed resolution.]</i></p> |
| |
| <p><i>[Tokyo - The LWG noted that issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#216">216</a> involves |
| the same paragraphs.]</i></p> |
| |
| <p><i>[Post-Tokyo: The issues list maintainer combined the proposed |
| resolution of this issue with the proposed resolution for issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#216">216</a> as they both involved the same paragraphs, and were so |
| intertwined that dealing with them separately appear fraught with |
| error. The full text was supplied by Bill Plauger; it was cross |
| checked against changes supplied by Andy Sawyer. It should be further |
| checked by the LWG.]</i></p> |
| <hr> |
| <a name="184"><h3>184. numeric_limits<bool> wording problems</h3></a><p><b>Section:</b> 18.2.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.numeric.special"> [lib.numeric.special]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Gabriel Dos Reis <b>Date:</b> 21 Jul 1999</p> |
| <p>bools are defined by the standard to be of integer types, as per |
| 3.9.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/basic.html#basic.fundamental"> [basic.fundamental]</a> paragraph 7. However "integer types" |
| seems to have a special meaning for the author of 18.2. The net effect |
| is an unclear and confusing specification for |
| numeric_limits<bool> as evidenced below.</p> |
| |
| <p>18.2.1.2/7 says numeric_limits<>::digits is, for built-in integer |
| types, the number of non-sign bits in the representation.</p> |
| |
| <p>4.5/4 states that a bool promotes to int ; whereas 4.12/1 says any non zero |
| arithmetical value converts to true.</p> |
| |
| <p>I don't think it makes sense at all to require |
| numeric_limits<bool>::digits and numeric_limits<bool>::digits10 to |
| be meaningful.</p> |
| |
| <p>The standard defines what constitutes a signed (resp. unsigned) integer |
| types. It doesn't categorize bool as being signed or unsigned. And the set of |
| values of bool type has only two elements.</p> |
| |
| <p>I don't think it makes sense to require numeric_limits<bool>::is_signed |
| to be meaningful.</p> |
| |
| <p>18.2.1.2/18 for numeric_limits<integer_type>::radix says:</p> |
| <blockquote> |
| <p>For integer types, specifies the base of the representation.186)</p> |
| </blockquote> |
| |
| <p>This disposition is at best misleading and confusing for the standard |
| requires a "pure binary numeration system" for integer types as per |
| 3.9.1/7</p> |
| |
| <p>The footnote 186) says: "Distinguishes types with base other than 2 (e.g |
| BCD)." This also erroneous as the standard never defines any integer |
| types with base representation other than 2.</p> |
| |
| <p>Furthermore, numeric_limits<bool>::is_modulo and |
| numeric_limits<bool>::is_signed have similar problems.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Append to the end of 18.2.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.numeric.special"> [lib.numeric.special]</a>:</p> |
| <blockquote> |
| <p>The specialization for bool shall be provided as follows:</p> |
| <pre> namespace std { |
| template<> class numeric_limits<bool> { |
| public: |
| static const bool is_specialized = true; |
| static bool min() throw() { return false; } |
| static bool max() throw() { return true; } |
| |
| static const int digits = 1; |
| static const int digits10 = 0; |
| static const bool is_signed = false; |
| static const bool is_integer = true; |
| static const bool is_exact = true; |
| static const int radix = 2; |
| static bool epsilon() throw() { return 0; } |
| static bool round_error() throw() { return 0; } |
| |
| static const int min_exponent = 0; |
| static const int min_exponent10 = 0; |
| static const int max_exponent = 0; |
| static const int max_exponent10 = 0; |
| |
| static const bool has_infinity = false; |
| static const bool has_quiet_NaN = false; |
| static const bool has_signaling_NaN = false; |
| static const float_denorm_style has_denorm = denorm_absent; |
| static const bool has_denorm_loss = false; |
| static bool infinity() throw() { return 0; } |
| static bool quiet_NaN() throw() { return 0; } |
| static bool signaling_NaN() throw() { return 0; } |
| static bool denorm_min() throw() { return 0; } |
| |
| static const bool is_iec559 = false; |
| static const bool is_bounded = true; |
| static const bool is_modulo = false; |
| |
| static const bool traps = false; |
| static const bool tinyness_before = false; |
| static const float_round_style round_style = round_toward_zero; |
| }; |
| }</pre> |
| </blockquote> |
| |
| <p><i>[Tokyo: The LWG desires wording that specifies exact values |
| rather than more general wording in the original proposed |
| resolution.]</i></p> |
| |
| <p><i>[Post-Tokyo: At the request of the LWG in Tokyo, Nico |
| Josuttis provided the above wording.]</i></p> |
| <hr> |
| <a name="185"><h3>185. Questionable use of term "inline"</h3></a><p><b>Section:</b> 20.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.tuple"> [lib.tuple]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> UK Panel <b>Date:</b> 26 Jul 1999</p> |
| <p>Paragraph 4 of 20.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.tuple"> [lib.tuple]</a> says:</p> |
| <blockquote> |
| <p> [Example: To negate every element of a: transform(a.begin(), a.end(), |
| a.begin(), negate<double>()); The corresponding functions will inline |
| the addition and the negation. end example]</p> |
| </blockquote> |
| <p>(Note: The "addition" referred to in the above is in para 3) we can |
| find no other wording, except this (non-normative) example which suggests that |
| any "inlining" will take place in this case.</p> |
| <p>Indeed both:</p> |
| <blockquote> |
| <p>17.4.4.3 Global Functions [lib.global.functions] 1 It is |
| unspecified whether any global functions in the C++ Standard Library |
| are defined as inline (7.1.2).</p> |
| </blockquote> |
| <p>and</p> |
| <blockquote> |
| <p>17.4.4.4 Member Functions [lib.member.functions] 1 It is |
| unspecified whether any member functions in the C++ Standard Library |
| are defined as inline (7.1.2).</p> |
| </blockquote> |
| <p>take care to state that this may indeed NOT be the case.</p> |
| <p>Thus the example "mandates" behavior that is explicitly |
| not required elsewhere.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 20.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.tuple"> [lib.tuple]</a> paragraph 1, remove the sentence:</p> |
| <blockquote> |
| <p>They are important for the effective use of the library.</p> |
| </blockquote> |
| <p>Remove 20.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.tuple"> [lib.tuple]</a> paragraph 2, which reads:</p> |
| <blockquote> |
| <p> Using function objects together with function templates |
| increases the expressive power of the library as well as making the |
| resulting code much more efficient.</p> |
| </blockquote> |
| <p>In 20.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.tuple"> [lib.tuple]</a> paragraph 4, remove the sentence:</p> |
| <blockquote> |
| <p>The corresponding functions will inline the addition and the |
| negation.</p> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG agreed there was a defect.]</i></p> |
| <p><i>[Tokyo: The LWG crafted the proposed resolution.]</i></p> |
| <hr> |
| <a name="186"><h3>186. bitset::set() second parameter should be bool</h3></a><p><b>Section:</b> 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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Darin Adler <b>Date:</b> 13 Aug 1999</p> |
| <p>In section 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>, paragraph 13 defines the |
| bitset::set operation to take a second parameter of type int. The |
| function tests whether this value is non-zero to determine whether to |
| set the bit to true or false. The type of this second parameter should |
| be bool. For one thing, the intent is to specify a Boolean value. For |
| another, the result type from test() is bool. In addition, it's |
| possible to slice an integer that's larger than an int. This can't |
| happen with bool, since conversion to bool has the semantic of |
| translating 0 to false and any non-zero value to true.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.template.bitset"> [lib.template.bitset]</a> Para 1 Replace:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, int val = true ); </pre> |
| </blockquote> |
| <p>With:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, bool val = true );</pre> |
| </blockquote> |
| <p>In 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> Para 12(.5) Replace:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, int val = 1 );</pre> |
| </blockquote> |
| <p>With:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, bool val = true );</pre> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG agrees with the description. Andy Sawyer will work |
| on better P/R wording.]</i></p> |
| <p><i>[Post-Tokyo: Andy provided the above wording.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p><tt>bool</tt> is a better choice. It is believed that binary |
| compatibility is not an issue, because this member function is |
| usually implemented as <tt>inline</tt>, and because it is already |
| the case that users cannot rely on the type of a pointer to a |
| nonvirtual member of a standard library class.</p> |
| <hr> |
| <a name="187"><h3>187. iter_swap underspecified</h3></a><p><b>Section:</b> 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#WP">WP</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 14 Aug 1999</p> |
| <p>The description of iter_swap in 25.2.2 paragraph 7,says that it |
| ``exchanges the values'' of the objects to which two iterators |
| refer.<br> <br> What it doesn't say is whether it does so using swap |
| or using the assignment operator and copy constructor.<br> <br> This |
| question is an important one to answer, because swap is specialized to |
| work efficiently for standard containers.<br> For example:</p> |
| <blockquote> |
| <pre>vector<int> v1, v2; |
| iter_swap(&v1, &v2);</pre> |
| </blockquote> |
| <p>Is this call to iter_swap equivalent to calling swap(v1, v2)? |
| Or is it equivalent to</p> |
| <blockquote> |
| <pre>{ |
| vector<int> temp = v1; |
| v1 = v2; |
| v2 = temp; |
| }</pre> |
| </blockquote> |
| <p>The first alternative is O(1); the second is O(n).</p> |
| <p>A LWG member, Dave Abrahams, comments:</p> |
| <blockquote> |
| <p>Not an objection necessarily, but I want to point out the cost of |
| that requirement:</p> |
| <blockquote> |
| <p><tt>iter_swap(list<T>::iterator, list<T>::iterator)</tt></p> |
| </blockquote> |
| <p>can currently be specialized to be more efficient than |
| iter_swap(T*,T*) for many T (by using splicing). Your proposal would |
| make that optimization illegal. </p> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG notes the original need for iter_swap was proxy iterators |
| which are no longer permitted.]</i></p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the effect clause of iter_swap in 25.2.2 paragraph 7 from:</p> |
| <blockquote> |
| <p>Exchanges the values pointed to by the two iterators a and b.</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p><tt>swap(*a, *b)</tt>.</p> |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p>It's useful to say just what <tt>iter_swap</tt> does. There may be |
| some iterators for which we want to specialize <tt>iter_swap</tt>, |
| but the fully general version should have a general specification.</p> |
| |
| <p>Note that in the specific case of <tt>list<T>::iterator</tt>, |
| iter_swap should not be specialized as suggested above. That would do |
| much more than exchanging the two iterators' values: it would change |
| predecessor/successor relationships, possibly moving the iterator from |
| one list to another. That would surely be inappropriate.</p> |
| <hr> |
| <a name="189"><h3>189. setprecision() not specified correctly</h3></a><p><b>Section:</b> 27.4.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fmtflags.state"> [lib.fmtflags.state]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 25 Aug 1999</p> |
| <p>27.4.2.2 paragraph 9 claims that setprecision() sets the precision, |
| and includes a parenthetical note saying that it is the number of |
| digits after the decimal point.<br> |
| <br> |
| This claim is not strictly correct. For example, in the default |
| floating-point output format, setprecision sets the number of |
| significant digits printed, not the number of digits after the decimal |
| point.<br> |
| <br> |
| I would like the committee to look at the definition carefully and |
| correct the statement in 27.4.2.2</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove from 27.4.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fmtflags.state"> [lib.fmtflags.state]</a>, paragraph 9, the text |
| "(number of digits after the decimal point)".</p> |
| <hr> |
| <a name="193"><h3>193. Heap operations description incorrect</h3></a><p><b>Section:</b> 25.3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.heap.operations"> [lib.alg.heap.operations]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Markus Mauhart <b>Date:</b> 24 Sep 1999</p> |
| <p>25.3.6 [lib.alg.heap.operations] states two key properties of a heap [a,b), the first of them |
| is<br> |
| <br> |
| `"(1) *a is the largest element"<br> |
| <br> |
| I think this is incorrect and should be changed to the wording in the proposed |
| resolution.</p> |
| <p>Actually there are two independent changes:</p> |
| <blockquote> |
| <p>A-"part of largest equivalence class" instead of "largest", cause 25.3 |
| [lib.alg.sorting] asserts "strict weak ordering" for all its sub clauses.</p> |
| <p>B-Take |
| 'an oldest' from that equivalence class, otherwise the heap functions |
| could not be used for a priority queue as explained in 23.2.3.2.2 |
| [lib.priqueue.members] (where I assume that a "priority queue" respects |
| priority AND time).</p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.heap.operations"> [lib.alg.heap.operations]</a> property (1) from:</p> |
| <blockquote> |
| <p>(1) *a is the largest element</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>(1) There is no element greater than <tt>*a</tt></p> |
| </blockquote> |
| <hr> |
| <a name="195"><h3>195. Should <tt>basic_istream::sentry</tt>'s constructor ever set eofbit?</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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 13 Oct 1999</p> |
| <p>Suppose that <tt>is.flags() & ios_base::skipws</tt> is nonzero. |
| What should <tt>basic_istream<>::sentry</tt>'s constructor do if it |
| reaches eof while skipping whitespace? 27.6.1.1.2/5 suggests it |
| should set failbit. Should it set eofbit as well? The standard |
| doesn't seem to answer that question.</p> |
| |
| <p>On the one hand, nothing in 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> says that |
| <tt>basic_istream<>::sentry</tt> should ever set eofbit. On the |
| other hand, 27.6.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream"> [lib.istream]</a> paragraph 4 says that if |
| extraction from a <tt>streambuf</tt> "returns |
| <tt>traits::eof()</tt>, then the input function, except as explicitly |
| noted otherwise, completes its actions and does |
| <tt>setstate(eofbit)"</tt>. So the question comes down to |
| whether <tt>basic_istream<>::sentry</tt>'s constructor is an |
| input function.</p> |
| |
| <p>Comments from Jerry Schwarz:</p> |
| <blockquote> |
| <p>It was always my intention that eofbit should be set any time that a |
| virtual returned something to indicate eof, no matter what reason |
| iostream code had for calling the virtual.</p> |
| <p> |
| The motivation for this is that I did not want to require streambufs |
| to behave consistently if their virtuals are called after they have |
| signaled eof.</p> |
| <p> |
| The classic case is a streambuf reading from a UNIX file. EOF isn't |
| really a state for UNIX file descriptors. The convention is that a |
| read on UNIX returns 0 bytes to indicate "EOF", but the file |
| descriptor isn't shut down in any way and future reads do not |
| necessarily also return 0 bytes. In particular, you can read from |
| tty's on UNIX even after they have signaled "EOF". (It |
| isn't always understood that a ^D on UNIX is not an EOF indicator, but |
| an EOL indicator. By typing a "line" consisting solely of |
| ^D you cause a read to return 0 bytes, and by convention this is |
| interpreted as end of file.)</p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a sentence to the end of 27.6.1.1.2 paragraph 2:</p> |
| <blockquote> |
| <p>If <tt>is.rdbuf()->sbumpc()</tt> or <tt>is.rdbuf()->sgetc()</tt> |
| returns <tt>traits::eof()</tt>, the function calls |
| <tt>setstate(failbit | eofbit)</tt> (which may throw |
| <tt>ios_base::failure</tt>). |
| </p> |
| </blockquote> |
| <hr> |
| <a name="198"><h3>198. Validity of pointers and references unspecified after iterator destruction</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#WP">WP</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 3 Nov 1999</p> |
| <p> |
| Is a pointer or reference obtained from an iterator still valid after |
| destruction of the iterator? |
| </p> |
| <p> |
| Is a pointer or reference obtained from an iterator still valid after the value |
| of the iterator changes? |
| </p> |
| <blockquote> |
| <pre>#include <iostream> |
| #include <vector> |
| #include <iterator> |
| |
| int main() |
| { |
| typedef std::vector<int> vec_t; |
| vec_t v; |
| v.push_back( 1 ); |
| |
| // Is a pointer or reference obtained from an iterator still |
| // valid after destruction of the iterator? |
| int * p = &*v.begin(); |
| std::cout << *p << '\n'; // OK? |
| |
| // Is a pointer or reference obtained from an iterator still |
| // valid after the value of the iterator changes? |
| vec_t::iterator iter( v.begin() ); |
| p = &*iter++; |
| std::cout << *p << '\n'; // OK? |
| |
| return 0; |
| } |
| </pre> |
| </blockquote> |
| |
| <p>The standard doesn't appear to directly address these |
| questions. The standard needs to be clarified. At least two real-world |
| cases have been reported where library implementors wasted |
| considerable effort because of the lack of clarity in the |
| standard. The question is important because requiring pointers and |
| references to remain valid has the effect for practical purposes of |
| prohibiting iterators from pointing to cached rather than actual |
| elements of containers.</p> |
| |
| <p>The standard itself assumes that pointers and references obtained |
| from an iterator are still valid after iterator destruction or |
| change. The definition of reverse_iterator::operator*(), 24.4.1.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.conv"> [lib.reverse.iter.conv]</a>, which returns a reference, defines |
| effects:</p> |
| |
| <blockquote> |
| <pre>Iterator tmp = current; |
| return *--tmp;</pre> |
| </blockquote> |
| <p>The definition of reverse_iterator::operator->(), 24.4.1.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.op.star"> [lib.reverse.iter.op.star]</a>, which returns a pointer, defines effects:</p> |
| <blockquote> |
| <pre>return &(operator*());</pre> |
| </blockquote> |
| |
| <p>Because the standard itself assumes pointers and references remain |
| valid after iterator destruction or change, the standard should say so |
| explicitly. This will also reduce the chance of user code breaking |
| unexpectedly when porting to a different standard library |
| implementation.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a new paragraph to 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>:</p> |
| <blockquote> |
| Destruction of an iterator may invalidate pointers and references |
| previously obtained from that iterator. |
| </blockquote> |
| |
| <p>Replace paragraph 1 of 24.4.1.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.conv"> [lib.reverse.iter.conv]</a> with:</p> |
| |
| <blockquote> |
| <p><b>Effects:</b></p> |
| <pre> this->tmp = current; |
| --this->tmp; |
| return *this->tmp; |
| </pre> |
| |
| <p> |
| [<i>Note:</i> This operation must use an auxiliary member variable, |
| rather than a temporary variable, to avoid returning a reference that |
| persists beyond the lifetime of its associated iterator. (See |
| 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>.) The name of this member variable is shown for |
| exposition only. <i>--end note</i>] |
| </p> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: The issue has been reformulated purely |
| in terms of iterators.]</i></p> |
| |
| <p><i>[Pre-Toronto: Steve Cleary pointed out the no-invalidation |
| assumption by reverse_iterator. The issue and proposed resolution was |
| reformulated yet again to reflect this reality.]</i></p> |
| |
| <p><i>[Copenhagen: Steve Cleary pointed out that reverse_iterator |
| assumes its underlying iterator has persistent pointers and |
| references. Andy Koenig pointed out that it is possible to rewrite |
| reverse_iterator so that it no longer makes such an assupmption. |
| However, this issue is related to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a>. If we |
| decide it is intentional that <tt>p[n]</tt> may return by value |
| instead of reference when <tt>p</tt> is a Random Access Iterator, |
| other changes in reverse_iterator will be necessary.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p>This issue has been discussed extensively. Note that it is |
| <i>not</i> an issue about the behavior of predefined iterators. It is |
| asking whether or not user-defined iterators are permitted to have |
| transient pointers and references. Several people presented examples |
| of useful user-defined iterators that have such a property; examples |
| include a B-tree iterator, and an "iota iterator" that doesn't point |
| to memory. Library implementors already seem to be able to cope with |
| such iterators: they take pains to avoid forming references to memory |
| that gets iterated past. The only place where this is a problem is |
| <tt>reverse_iterator</tt>, so this issue changes |
| <tt>reverse_iterator</tt> to make it work.</p> |
| |
| <p>This resolution does not weaken any guarantees provided by |
| predefined iterators like <tt>list<int>::iterator</tt>. |
| Clause 23 should be reviewed to make sure that guarantees for |
| predefined iterators are as strong as users expect.</p> |
| |
| <hr> |
| <a name="199"><h3>199. What does <tt>allocate(0)</tt> return?</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#TC">TC</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 19 Nov 1999</p> |
| <p> |
| Suppose that <tt>A</tt> is a class that conforms to the |
| Allocator requirements of Table 32, and <tt>a</tt> is an |
| object of class <tt>A</tt> What should be the return |
| value of <tt>a.allocate(0)</tt>? Three reasonable |
| possibilities: forbid the argument <tt>0</tt>, return |
| a null pointer, or require that the return value be a |
| unique non-null pointer. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a note to the <tt>allocate</tt> row of Table 32: |
| "[<i>Note:</i> If <tt>n == 0</tt>, the return value is unspecified. <i>--end note</i>]"</p> |
| <p><b>Rationale:</b></p> |
| <p>A key to understanding this issue is that the ultimate use of |
| allocate() is to construct an iterator, and that iterator for zero |
| length sequences must be the container's past-the-end |
| representation. Since this already implies special case code, it |
| would be over-specification to mandate the return value. |
| </p> |
| <hr> |
| <a name="200"><h3>200. Forward iterator requirements don't allow constant iterators</h3></a><p><b>Section:</b> 24.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.forward.iterators"> [lib.forward.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 19 Nov 1999</p> |
| <p> |
| In table 74, the return type of the expression <tt>*a</tt> is given |
| as <tt>T&</tt>, where <tt>T</tt> is the iterator's value type. |
| For constant iterators, however, this is wrong. ("Value type" |
| is never defined very precisely, but it is clear that the value type |
| of, say, <tt>std::list<int>::const_iterator</tt> is supposed to be |
| <tt>int</tt>, not <tt>const int</tt>.) |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In table 74, in the <tt>*a</tt> and <tt>*r++</tt> rows, change the |
| return type from "<tt>T&</tt>" to "<tt>T&</tt> |
| if <tt>X</tt> is mutable, otherwise <tt>const T&</tt>". |
| In the <tt>a->m</tt> row, change the return type from |
| "<tt>U&</tt>" to "<tt>U&</tt> if <tt>X</tt> is mutable, |
| otherwise <tt>const U&</tt>". |
| </p> |
| |
| <p><i>[Tokyo: The LWG believes this is the tip of a larger iceberg; |
| there are multiple const problems with the STL portion of the library |
| and that these should be addressed as a single package. Note |
| that issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#180">180</a> has already been declared NAD Future for |
| that very reason.]</i></p> |
| |
| <p><i>[Redmond: the LWG thinks this is separable from other constness |
| issues. This issue is just cleanup; it clarifies language that was |
| written before we had iterator_traits. Proposed resolution was |
| modified: the original version only discussed *a. It was pointed out |
| that we also need to worry about *r++ and a->m.]</i></p> |
| |
| <hr> |
| <a name="202"><h3>202. unique() effects unclear when predicate not an equivalence relation</h3></a><p><b>Section:</b> 25.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 13 Jan 2000</p> |
| <p> |
| What should unique() do if you give it a predicate that is not an |
| equivalence relation? There are at least two plausible answers: |
| </p> |
| |
| <blockquote> |
| |
| <p> |
| 1. You can't, because 25.2.8 says that it it "eliminates all but |
| the first element from every consecutive group of equal |
| elements..." and it wouldn't make sense to interpret "equal" as |
| meaning anything but an equivalence relation. [It also doesn't |
| make sense to interpret "equal" as meaning ==, because then there |
| would never be any sense in giving a predicate as an argument at |
| all.] |
| </p> |
| |
| <p> |
| 2. The word "equal" should be interpreted to mean whatever the |
| predicate says, even if it is not an equivalence relation |
| (and in particular, even if it is not transitive). |
| </p> |
| |
| </blockquote> |
| |
| <p> |
| The example that raised this question is from Usenet: |
| </p> |
| |
| <blockquote> |
| |
| <pre>int f[] = { 1, 3, 7, 1, 2 }; |
| int* z = unique(f, f+5, greater<int>());</pre> |
| |
| </blockquote> |
| |
| <p> |
| If one blindly applies the definition using the predicate |
| greater<int>, and ignore the word "equal", you get: |
| </p> |
| |
| <blockquote> |
| |
| <p> |
| Eliminates all but the first element from every consecutive group |
| of elements referred to by the iterator i in the range [first, last) |
| for which *i > *(i - 1). |
| </p> |
| |
| </blockquote> |
| |
| <p> |
| The first surprise is the order of the comparison. If we wanted to |
| allow for the predicate not being an equivalence relation, then we |
| should surely compare elements the other way: pred(*(i - 1), *i). If |
| we do that, then the description would seem to say: "Break the |
| sequence into subsequences whose elements are in strictly increasing |
| order, and keep only the first element of each subsequence". So the |
| result would be 1, 1, 2. If we take the description at its word, it |
| would seem to call for strictly DEcreasing order, in which case the |
| result should be 1, 3, 7, 2.<br> |
| <br> |
| In fact, the SGI implementation of unique() does neither: It yields 1, |
| 3, 7. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> paragraph 1 to:</p> |
| <blockquote> |
| For a nonempty range, eliminates all but the first element from every |
| consecutive group of equivalent elements referred to by the iterator |
| <tt>i</tt> in the range [first+1, last) for which the following |
| conditions hold: <tt>*(i-1) == *i</tt> or <tt>pred(*(i-1), *i) != |
| false</tt>. |
| </blockquote> |
| |
| <p> |
| Also insert a new paragraph, paragraph 2a, that reads: "Requires: The |
| comparison function must be an equivalence relation." |
| </p> |
| |
| <p><i>[Redmond: discussed arguments for and against requiring the |
| comparison function to be an equivalence relation. Straw poll: |
| 14-2-5. First number is to require that it be an equivalence |
| relation, second number is to explicitly not require that it be an |
| equivalence relation, third number is people who believe they need |
| more time to consider the issue. A separate issue: Andy Sawyer |
| pointed out that "i-1" is incorrect, since "i" can refer to the first |
| iterator in the range. Matt provided wording to address this |
| problem.]</i></p> |
| |
| <p><i>[Curaçao: The LWG changed "... the range (first, |
| last)..." to "... the range [first+1, last)..." for |
| clarity. They considered this change close enough to editorial to not |
| require another round of review.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG also considered an alternative resolution: change |
| 25.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> paragraph 1 to:</p> |
| |
| <blockquote> |
| For a nonempty range, eliminates all but the first element from every |
| consecutive group of elements referred to by the iterator |
| <tt>i</tt> in the range (first, last) for which the following |
| conditions hold: <tt>*(i-1) == *i</tt> or <tt>pred(*(i-1), *i) != |
| false</tt>. |
| </blockquote> |
| |
| <p> |
| Also insert a new paragraph, paragraph 1a, that reads: "Notes: The |
| comparison function need not be an equivalence relation." |
| </p> |
| |
| |
| <p>Informally: the proposed resolution imposes an explicit requirement |
| that the comparison function be an equivalence relation. The |
| alternative resolution does not, and it gives enough information so |
| that the behavior of unique() for a non-equivalence relation is |
| specified. Both resolutions are consistent with the behavior of |
| existing implementations.</p> |
| <hr> |
| <a name="208"><h3>208. Unnecessary restriction on past-the-end iterators</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#TC">TC</a> <b>Submitter:</b> Stephen Cleary <b>Date:</b> 02 Feb 2000</p> |
| <p>In 24.1 paragraph 5, it is stated ". . . Dereferenceable and |
| past-the-end values are always non-singular."</p> |
| <p>This places an unnecessary restriction on past-the-end iterators for |
| containers with forward iterators (for example, a singly-linked list). If the |
| past-the-end value on such a container was a well-known singular value, it would |
| still satisfy all forward iterator requirements.</p> |
| <p>Removing this restriction would allow, for example, a singly-linked list |
| without a "footer" node.</p> |
| <p>This would have an impact on existing code that expects past-the-end |
| iterators obtained from different (generic) containers being not equal.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a> paragraph 5, the last sentence, from:</p> |
| <blockquote> |
| <p>Dereferenceable and past-the-end values are always non-singular.</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Dereferenceable values are always non-singular. </p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>For some kinds of containers, including singly linked lists and |
| zero-length vectors, null pointers are perfectly reasonable past-the-end |
| iterators. Null pointers are singular. |
| </p> |
| <hr> |
| <a name="209"><h3>209. basic_string declarations inconsistent</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#TC">TC</a> <b>Submitter:</b> Igor Stauder <b>Date:</b> 11 Feb 2000</p> |
| <p>In Section 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a> the basic_string member function |
| declarations use a consistent style except for the following functions:</p> |
| <blockquote> |
| <pre>void push_back(const charT); |
| basic_string& assign(const basic_string&); |
| void swap(basic_string<charT,traits,Allocator>&);</pre> |
| </blockquote> |
| <p>- push_back, assign, swap: missing argument name <br> |
| - push_back: use of const with charT (i.e. POD type passed by value |
| not by reference - should be charT or const charT& )<br> |
| - swap: redundant use of template parameters in argument |
| basic_string<charT,traits,Allocator>&</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In Section 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a> change the basic_string member |
| function declarations push_back, assign, and swap to:</p> |
| <blockquote> |
| <pre>void push_back(charT c); |
| |
| basic_string& assign(const basic_string& str); |
| void swap(basic_string& str);</pre> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Although the standard is in general not consistent in declaration |
| style, the basic_string declarations are consistent other than the |
| above. The LWG felt that this was sufficient reason to merit the |
| change. |
| </p> |
| <hr> |
| <a name="210"><h3>210. distance first and last confused</h3></a><p><b>Section:</b> 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#TC">TC</a> <b>Submitter:</b> Lisa Lippincott <b>Date:</b> 15 Feb 2000</p> |
| <p>In paragraph 9 of section 25 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a>, it is written:</p> |
| <blockquote> |
| <p> In the description of the algorithms operators + 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-b is the same |
| as of<br> |
| <br> |
| <tt>return distance(a, b);</tt></p> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>On the last line of paragraph 9 of section 25 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a> change |
| <tt>"a-b"</tt> to <tt>"b-a".</tt></p> |
| <p><b>Rationale:</b></p> |
| <p>There are two ways to fix the defect; change the description to b-a |
| or change the return to distance(b,a). The LWG preferred the |
| former for consistency.</p> |
| <hr> |
| <a name="211"><h3>211. operator>>(istream&, string&) doesn't set failbit</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#TC">TC</a> <b>Submitter:</b> Scott Snyder <b>Date:</b> 4 Feb 2000</p> |
| <p>The description of the stream extraction operator for std::string (section |
| 21.3.7.9 [lib.string.io]) does not contain a requirement that failbit be set in |
| the case that the operator fails to extract any characters from the input |
| stream.</p> |
| <p>This implies that the typical construction</p> |
| <blockquote> |
| <pre>std::istream is; |
| std::string str; |
| ... |
| while (is >> str) ... ;</pre> |
| </blockquote> |
| <p>(which tests failbit) is not required to terminate at EOF.</p> |
| <p>Furthermore, this is inconsistent with other extraction operators, |
| which do include this requirement. (See sections 27.6.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted"> [lib.istream.formatted]</a> and 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>), where this |
| requirement is present, either explicitly or implicitly, for the |
| extraction operators. It is also present explicitly in the description |
| of getline (istream&, string&, charT) in section 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> paragraph 8.)</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Insert new paragraph after paragraph 2 in section 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>:</p> |
| <blockquote> |
| |
| <p>If the function extracts no characters, it calls |
| is.setstate(ios::failbit) which may throw ios_base::failure |
| (27.4.4.3).</p> |
| </blockquote> |
| <hr> |
| <a name="212"><h3>212. Empty range behavior unclear for several algorithms</h3></a><p><b>Section:</b> 25.3.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.min.max"> [lib.alg.min.max]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 26 Feb 2000</p> |
| <p>The standard doesn't specify what min_element() and max_element() shall |
| return if the range is empty (first equals last). The usual implementations |
| return last. This problem seems also apply to partition(), stable_partition(), |
| next_permutation(), and prev_permutation().</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.3.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.min.max"> [lib.alg.min.max]</a> - Minimum and maximum, paragraphs 7 and |
| 9, append: Returns last if first==last.</p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG looked in some detail at all of the above mentioned |
| algorithms, but believes that except for min_element() and |
| max_element() it is already clear that last is returned if first == |
| last.</p> |
| <hr> |
| <a name="214"><h3>214. set::find() missing const overload</h3></a><p><b>Section:</b> 23.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.set"> [lib.set]</a>, 23.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.multiset"> [lib.multiset]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 28 Feb 2000</p> |
| <p>The specification for the associative container requirements in |
| Table 69 state that the find member function should "return |
| iterator; const_iterator for constant a". The map and multimap |
| container descriptions have two overloaded versions of find, but set |
| and multiset do not, all they have is:</p> |
| <blockquote> |
| <pre>iterator find(const key_type & x) const;</pre> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the prototypes for find(), lower_bound(), upper_bound(), and |
| equal_range() in section 23.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.set"> [lib.set]</a> and section 23.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.multiset"> [lib.multiset]</a> to each have two overloads:</p> |
| <blockquote> |
| <pre>iterator find(const key_type & x); |
| const_iterator find(const key_type & x) const;</pre> |
| <pre>iterator lower_bound(const key_type & x); |
| const_iterator lower_bound(const key_type & x) const;</pre> |
| <pre>iterator upper_bound(const key_type & x); |
| const_iterator upper_bound(const key_type & x) const;</pre> |
| <pre>pair<iterator, iterator> equal_range(const key_type & x); |
| pair<const_iterator, const_iterator> equal_range(const key_type & x) const;</pre> |
| </blockquote> |
| |
| <p><i>[Tokyo: At the request of the LWG, Judy Ward provided wording |
| extending the proposed resolution to lower_bound, upper_bound, and |
| equal_range.]</i></p> |
| <hr> |
| <a name="217"><h3>217. Facets example (Classifying Japanese characters) contains errors</h3></a><p><b>Section:</b> 22.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facets.examples"> [lib.facets.examples]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 29 Feb 2000</p> |
| <p>The example in 22.2.8, paragraph 11 contains the following errors:</p> |
| <p>1) The member function `My::JCtype::is_kanji()' is non-const; the function |
| must be const in order for it to be callable on a const object (a reference to |
| which which is what std::use_facet<>() returns).</p> |
| <p>2) In file filt.C, the definition of `JCtype::id' must be qualified with the |
| name of the namespace `My'.</p> |
| <p>3) In the definition of `loc' and subsequently in the call to use_facet<>() |
| in main(), the name of the facet is misspelled: it should read `My::JCtype' |
| rather than `My::JCType'.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the "Classifying Japanese characters" example in 22.2.8, |
| paragraph 11 with the following:</p> |
| <pre>#include <locale></pre> |
| <pre>namespace My { |
| using namespace std; |
| class JCtype : public locale::facet { |
| public: |
| static locale::id id; // required for use as a new locale facet |
| bool is_kanji (wchar_t c) const; |
| JCtype() {} |
| protected: |
| ~JCtype() {} |
| }; |
| }</pre> |
| <pre>// file: filt.C |
| #include <iostream> |
| #include <locale> |
| #include "jctype" // above |
| std::locale::id My::JCtype::id; // the static JCtype member |
| declared above.</pre> |
| <pre>int main() |
| { |
| using namespace std; |
| typedef ctype<wchar_t> wctype; |
| locale loc(locale(""), // the user's preferred locale... |
| new My::JCtype); // and a new feature ... |
| wchar_t c = use_facet<wctype>(loc).widen('!'); |
| if (!use_facet<My::JCtype>(loc).is_kanji(c)) |
| cout << "no it isn't!" << endl; |
| return 0; |
| }</pre> |
| <hr> |
| <a name="220"><h3>220. ~ios_base() usage valid?</h3></a><p><b>Section:</b> 27.4.2.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios.base.cons"> [lib.ios.base.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Jonathan Schilling, Howard Hinnant <b>Date:</b> 13 Mar 2000</p> |
| <p>The pre-conditions for the ios_base destructor are described in 27.4.2.7 |
| paragraph 2:</p> |
| <blockquote> |
| <p>Effects: Destroys an object of class ios_base. Calls each registered |
| callback pair (fn,index) (27.4.2.6) as (*fn)(erase_event,*this,index) at such |
| time that any ios_base member function called from within fn has well defined |
| results.</p> |
| </blockquote> |
| <p>But what is not clear is: If no callback functions were ever registered, does |
| it matter whether the ios_base members were ever initialized?</p> |
| <p>For instance, does this program have defined behavior:</p> |
| <blockquote> |
| <pre>#include <ios></pre> |
| <pre>class D : public std::ios_base { };</pre> |
| <pre>int main() { D d; }</pre> |
| </blockquote> |
| <p>It seems that registration of a callback function would surely affect the |
| state of an ios_base. That is, when you register a callback function with an |
| ios_base, the ios_base must record that fact somehow.</p> |
| <p>But if after construction the ios_base is in an indeterminate state, and that |
| state is not made determinate before the destructor is called, then how would |
| the destructor know if any callbacks had indeed been registered? And if the |
| number of callbacks that had been registered is indeterminate, then is not the |
| behavior of the destructor undefined?</p> |
| <p>By comparison, the basic_ios class description in 27.4.4.1 paragraph 2 makes |
| it explicit that destruction before initialization results in undefined |
| behavior.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Modify 27.4.2.7 paragraph 1 from</p> |
| <blockquote> |
| <p>Effects: Each ios_base member has an indeterminate value after |
| construction.</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p>Effects: Each ios_base member has an indeterminate |
| value after construction. These members must be initialized by calling |
| basic_ios::init. If an ios_base object is destroyed before these |
| initializations have taken place, the behavior is undefined.</p> |
| </blockquote> |
| <hr> |
| <a name="221"><h3>221. num_get<>::do_get stage 2 processing broken</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#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 14 Mar 2000</p> |
| <p>Stage 2 processing of numeric conversion is broken.</p> |
| |
| <p>Table 55 in 22.2.2.1.2 says that when basefield is 0 the integral |
| conversion specifier is %i. A %i specifier determines a number's base |
| by its prefix (0 for octal, 0x for hex), so the intention is clearly |
| that a 0x prefix is allowed. Paragraph 8 in the same section, |
| however, describes very precisely how characters are processed. (It |
| must be done "as if" by a specified code fragment.) That |
| description does not allow a 0x prefix to be recognized.</p> |
| |
| <p>Very roughly, stage 2 processing reads a char_type ct. It converts |
| ct to a char, not by using narrow but by looking it up in a |
| translation table that was created by widening the string literal |
| "0123456789abcdefABCDEF+-". The character "x" is |
| not found in that table, so it can't be recognized by stage 2 |
| processing.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.1.2 paragraph 8, replace the line:</p> |
| <blockquote> |
| <pre>static const char src[] = "0123456789abcdefABCDEF+-";</pre> |
| </blockquote> |
| <p>with the line:</p> |
| <blockquote> |
| <pre>static const char src[] = "0123456789abcdefxABCDEFX+-";</pre> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>If we're using the technique of widening a string literal, the |
| string literal must contain every character we wish to recognize. |
| This technique has the consequence that alternate representations |
| of digits will not be recognized. This design decision was made |
| deliberately, with full knowledge of that limitation.</p> |
| <hr> |
| <a name="222"><h3>222. Are throw clauses necessary if a throw is already implied by the effects clause?</h3></a><p><b>Section:</b> 17.3.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.structure.specifications"> [lib.structure.specifications]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 17 Mar 2000</p> |
| <p>Section 21.3.6.8 describes the basic_string::compare function this way:</p> |
| <blockquote> |
| <pre>21.3.6.8 - basic_string::compare [lib.string::compare] |
| |
| int compare(size_type pos1, size_type n1, |
| const basic_string<charT,traits,Allocator>& str , |
| size_type pos2 , size_type n2 ) const; |
| |
| -4- Returns: |
| |
| basic_string<charT,traits,Allocator>(*this,pos1,n1).compare( |
| basic_string<charT,traits,Allocator>(str,pos2,n2)) .</pre> |
| </blockquote> |
| <p>and the constructor that's implicitly called by the above is |
| defined to throw an out-of-range exception if pos > str.size(). See |
| section 21.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.cons"> [lib.string.cons]</a> paragraph 4.</p> |
| |
| <p>On the other hand, the compare function descriptions themselves don't have |
| "Throws: " clauses and according to 17.3.1.3, paragraph 3, elements |
| that do not apply to a function are omitted.</p> |
| <p>So it seems there is an inconsistency in the standard -- are the |
| "Effects" clauses correct, or are the "Throws" clauses |
| missing?</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 17.3.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.structure.specifications"> [lib.structure.specifications]</a> paragraph 3, the footnote 148 attached to |
| the sentence "Descriptions of function semantics contain the |
| following elements (as appropriate):", insert the word |
| "further" so that the foot note reads:</p> |
| <blockquote> |
| <p>To save space, items that do not apply to a function are |
| omitted. For example, if a function does not specify any further |
| preconditions, there will be no "Requires" paragraph.</p> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The standard is somewhat inconsistent, but a failure to note a |
| throw condition in a throws clause does not grant permission not to |
| throw. The inconsistent wording is in a footnote, and thus |
| non-normative. The proposed resolution from the LWG clarifies the |
| footnote.</p> |
| <hr> |
| <a name="223"><h3>223. reverse algorithm should use iter_swap rather than swap</h3></a><p><b>Section:</b> 25.2.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.reverse"> [lib.alg.reverse]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 21 Mar 2000</p> |
| <p>Shouldn't the effects say "applies iter_swap to all pairs..."?</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.2.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.reverse"> [lib.alg.reverse]</a>, replace:</p> |
| <blockquote> |
| Effects: For each non-negative integer i <= (last - first)/2, |
| applies swap to all pairs of iterators first + i, (last - i) - 1. |
| </blockquote> |
| <p>with:</p> |
| <blockquote> |
| Effects: For each non-negative integer i <= (last - first)/2, |
| applies iter_swap to all pairs of iterators first + i, (last - i) - 1. |
| </blockquote> |
| <hr> |
| <a name="224"></a><h3><a name="224">224. clear() complexity for associative containers refers to undefined N</a></h3><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#TC">TC</a> <b>Submitter:</b> Ed Brey <b>Date:</b> 23 Mar 2000</p> |
| <p>In the associative container requirements table in 23.1.2 paragraph 7, |
| a.clear() has complexity "log(size()) + N". However, the meaning of N |
| is not defined.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In the associative container requirements table in 23.1.2 paragraph |
| 7, the complexity of a.clear(), change "log(size()) + N" to |
| "linear in <tt>size()</tt>".</p> |
| <p><b>Rationale:</b></p> |
| <p>It's the "log(size())", not the "N", that is in |
| error: there's no difference between <i>O(N)</i> and <i>O(N + |
| log(N))</i>. The text in the standard is probably an incorrect |
| cut-and-paste from the range version of <tt>erase</tt>.</p> |
| <hr> |
| <a name="225"><h3>225. std:: algorithms use of other unqualified algorithms</h3></a><p><b>Section:</b> 17.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.global.functions"> [lib.global.functions]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 01 Apr 2000</p> |
| <p>Are algorithms in std:: allowed to use other algorithms without qualification, so functions in |
| user namespaces might be found through Koenig lookup?</p> |
| <p>For example, a popular standard library implementation includes this |
| implementation of std::unique:</p> |
| <blockquote> |
| <pre>namespace std { |
| template <class _ForwardIter> |
| _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { |
| __first = adjacent_find(__first, __last); |
| return unique_copy(__first, __last, __first); |
| } |
| }</pre> |
| </blockquote> |
| <p>Imagine two users on opposite sides of town, each using unique on his own |
| sequences bounded by my_iterators . User1 looks at his standard library |
| implementation and says, "I know how to implement a more efficient |
| unique_copy for my_iterators", and writes:</p> |
| <blockquote> |
| <pre>namespace user1 { |
| class my_iterator; |
| // faster version for my_iterator |
| my_iterator unique_copy(my_iterator, my_iterator, my_iterator); |
| }</pre> |
| </blockquote> |
| <p>user1::unique_copy() is selected by Koenig lookup, as he intended.</p> |
| <p>User2 has other needs, and writes:</p> |
| <blockquote> |
| <pre>namespace user2 { |
| class my_iterator; |
| // Returns true iff *c is a unique copy of *a and *b. |
| bool unique_copy(my_iterator a, my_iterator b, my_iterator c); |
| }</pre> |
| </blockquote> |
| <p>User2 is shocked to find later that his fully-qualified use of |
| std::unique(user2::my_iterator, user2::my_iterator, user2::my_iterator) fails to |
| compile (if he's lucky). Looking in the standard, he sees the following Effects |
| clause for unique():</p> |
| <blockquote> |
| <p>Effects: Eliminates all but the first element from every consecutive group |
| of equal elements referred to by the iterator i in the range [first, last) for |
| which the following corresponding conditions hold: *i == *(i - 1) or pred(*i, |
| *(i - 1)) != false</p> |
| </blockquote> |
| <p>The standard gives user2 absolutely no reason to think he can interfere with |
| std::unique by defining names in namespace user2. His standard library has been |
| built with the template export feature, so he is unable to inspect the |
| implementation. User1 eventually compiles his code with another compiler, and |
| his version of unique_copy silently stops being called. Eventually, he realizes |
| that he was depending on an implementation detail of his library and had no |
| right to expect his unique_copy() to be called portably.</p> |
| <p>On the face of it, and given above scenario, it may seem obvious that the |
| implementation of unique() shown is non-conforming because it uses unique_copy() |
| rather than ::std::unique_copy(). Most standard library implementations, |
| however, seem to disagree with this notion.</p> |
| <p> <i>[Tokyo: Steve Adamczyk from |
| the core working group indicates that "std::" is sufficient; |
| leading "::" qualification is not required because any namespace |
| qualification is sufficient to suppress Koenig lookup.]</i></p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a paragraph and a note at the end of |
| 17.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.global.functions"> [lib.global.functions]</a>:</p> |
| <blockquote> |
| |
| <p>Unless otherwise specified, no global or non-member function in the |
| standard library shall use a function from another namespace which is |
| found through <i>argument-dependent name lookup</i> (3.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/basic.html#basic.lookup.koenig"> [basic.lookup.koenig]</a>).</p> |
| |
| <p>[Note: the phrase "unless otherwise specified" is intended to |
| allow Koenig lookup in cases like that of ostream_iterators:<br> |
| |
| <br> |
| Effects:</p> |
| <blockquote> |
| <p>*out_stream << value;<br> |
| if(delim != 0) *out_stream << delim;<br> |
| return (*this);</p> |
| <p>--end note]</p> |
| </blockquote> |
| </blockquote> |
| |
| <p><i>[Tokyo: The LWG agrees that this is a defect in the standard, but |
| is as yet unsure if the proposed resolution is the best |
| solution. Furthermore, the LWG believes that the same problem of |
| unqualified library names applies to wording in the standard itself, |
| and has opened issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a> accordingly. Any resolution of |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a> should be coordinated with the resolution of |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a>.]</i></p> |
| |
| <p><i>[Toronto: The LWG is not sure if this is a defect in the |
| standard. Most LWG members believe that an implementation of |
| <tt>std::unique</tt> like the one quoted in this issue is already |
| illegal, since, under certain circumstances, its semantics are not |
| those specified in the standard. The standard's description of |
| <tt>unique</tt> does not say that overloading <tt>adjacent_find</tt> |
| should have any effect.]</i></p> |
| |
| <p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues |
| 225, 226, and 229. Their conclusion was that the issues should be |
| separated into an LWG portion (Howard's paper, N1387=02-0045), and a |
| EWG portion (Dave will write a proposal). The LWG and EWG had |
| (separate) discussions of this plan the next day. The proposed |
| resolution for this issue is in accordance with Howard's paper.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>It could be argued that this proposed isn't strictly necessary, |
| that the Standard doesn't grant implementors license to write a |
| standard function that behaves differently than specified in the |
| Standard just because of an unrelated user-defined name in some |
| other namespace. However, this is at worst a clarification. It is |
| surely right that algorithsm shouldn't pick up random names, that |
| user-defined names should have no effect unless otherwise specified. |
| Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a> deals with the question of when it is |
| appropriate for the standard to explicitly specify otherwise.</p> |
| <hr> |
| <a name="226"><h3>226. User supplied specializations or overloads of namespace std function 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#WP">WP</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 01 Apr 2000</p> |
| <p>The issues are: </p> |
| <p>1. How can a 3rd party library implementor (lib1) write a version of a standard |
| algorithm which is specialized to work with his own class template? </p> |
| <p>2. How can another library implementor (lib2) write a generic algorithm which |
| will take advantage of the specialized algorithm in lib1?</p> |
| <p>This appears to be the only viable answer under current language rules:</p> |
| <blockquote> |
| <pre>namespace lib1 |
| { |
| // arbitrary-precision numbers using T as a basic unit |
| template <class T> |
| class big_num { //... |
| }; |
| </pre> |
| <pre> // defining this in namespace std is illegal (it would be an |
| // overload), so we hope users will rely on Koenig lookup |
| template <class T> |
| void swap(big_int<T>&, big_int<T>&); |
| }</pre> |
| <pre>#include <algorithm> |
| namespace lib2 |
| { |
| template <class T> |
| void generic_sort(T* start, T* end) |
| { |
| ... |
| // using-declaration required so we can work on built-in types |
| using std::swap; |
| // use Koenig lookup to find specialized algorithm if available |
| swap(*x, *y); |
| } |
| }</pre> |
| </blockquote> |
| <p>This answer has some drawbacks. First of all, it makes writing lib2 difficult |
| and somewhat slippery. The implementor needs to remember to write the |
| using-declaration, or generic_sort will fail to compile when T is a built-in |
| type. The second drawback is that the use of this style in lib2 effectively |
| "reserves" names in any namespace which defines types which may |
| eventually be used with lib2. This may seem innocuous at first when applied to |
| names like swap, but consider more ambiguous names like unique_copy() instead. |
| It is easy to imagine the user wanting to define these names differently in his |
| own namespace. A definition with semantics incompatible with the standard |
| library could cause serious problems (see issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a>).</p> |
| <p>Why, you may ask, can't we just partially specialize std::swap()? It's |
| because the language doesn't allow for partial specialization of function |
| templates. If you write:</p> |
| <blockquote> |
| <pre>namespace std |
| { |
| template <class T> |
| void swap(lib1::big_int<T>&, lib1::big_int<T>&); |
| }</pre> |
| </blockquote> |
| <p>You have just overloaded std::swap, which is illegal under the current |
| language rules. On the other hand, the following full specialization is legal:</p> |
| <blockquote> |
| <pre>namespace std |
| { |
| template <> |
| void swap(lib1::other_type&, lib1::other_type&); |
| }</pre> |
| </blockquote> |
| |
| <p>This issue reflects concerns raised by the "Namespace issue |
| with specialized swap" thread on comp.lang.c++.moderated. A |
| similar set of concerns was earlier raised on the boost.org mailing |
| list and the ACCU-general mailing list. Also see library reflector |
| message c++std-lib-7354.</p> |
| |
| <p> |
| J. C. van Winkel points out (in c++std-lib-9565) another unexpected |
| fact: it's impossible to output a container of std::pair's using copy |
| and an ostream_iterator, as long as both pair-members are built-in or |
| std:: types. That's because a user-defined operator<< for (for |
| example) std::pair<const std::string, int> will not be found: |
| lookup for operator<< will be performed only in namespace std. |
| Opinions differed on whether or not this was a defect, and, if so, |
| whether the defect is that something is wrong with user-defined |
| functionality and std, or whether it's that the standard library does |
| not provide an operator<< for std::pair<>. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Adopt the wording proposed in Howard Hinnant's paper |
| N1523=03-0106, "Proposed Resolution To LWG issues 225, 226, 229".</p> |
| |
| |
| <p><i>[Tokyo: Summary, "There is no conforming way to extend |
| std::swap for user defined templates." The LWG agrees that |
| there is a problem. Would like more information before |
| proceeding. This may be a core issue. Core issue 229 has been opened |
| to discuss the core aspects of this problem. It was also noted that |
| submissions regarding this issue have been received from several |
| sources, but too late to be integrated into the issues list. |
| ]</i></p> |
| |
| <p><i>[Post-Tokyo: A paper with several proposed resolutions, |
| J16/00-0029==WG21/N1252, "Shades of namespace std functions |
| " by Alan Griffiths, is in the Post-Tokyo mailing. It |
| should be considered a part of this issue.]</i></p> |
| |
| <p><i>[Toronto: Dave Abrahams and Peter Dimov have proposed a |
| resolution that involves core changes: it would add partial |
| specialization of function template. The Core Working Group is |
| reluctant to add partial specialization of function templates. It is |
| viewed as a large change, CWG believes that proposal presented leaves |
| some syntactic issues unanswered; if the CWG does add partial |
| specialization of function templates, it wishes to develop its own |
| proposal. The LWG continues to believe that there is a serious |
| problem: there is no good way for users to force the library to use |
| user specializations of generic standard library functions, and in |
| certain cases (e.g. transcendental functions called by |
| <tt>valarray</tt> and <tt>complex</tt>) this is important. Koenig |
| lookup isn't adequate, since names within the library must be |
| qualified with <tt>std</tt> (see issue 225), specialization doesn't |
| work (we don't have partial specialization of function templates), and |
| users aren't permitted to add overloads within namespace std. |
| ]</i></p> |
| |
| <p><i>[Copenhagen: Discussed at length, with no consensus. Relevant |
| papers in the pre-Copenhagen mailing: N1289, N1295, N1296. Discussion |
| focused on four options. (1) Relax restrictions on overloads within |
| namespace std. (2) Mandate that the standard library use unqualified |
| calls for <tt>swap</tt> and possibly other functions. (3) Introduce |
| helper class templates for <tt>swap</tt> and possibly other functions. |
| (4) Introduce partial specialization of function templates. Every |
| option had both support and opposition. Straw poll (first number is |
| support, second is strongly opposed): (1) 6, 4; (2) 6, 7; (3) 3, 8; |
| (4) 4, 4.]</i></p> |
| |
| <p><i>[Redmond: Discussed, again no consensus. Herb presented an |
| argument that a user who is defining a type <tt>T</tt> with an |
| associated <tt>swap</tt> should not be expected to put that |
| <tt>swap</tt> in namespace std, either by overloading or by partial |
| specialization. The argument is that <tt>swap</tt> is part of |
| <tt>T</tt>'s interface, and thus should to in the same namespace as |
| <tt>T</tt> and only in that namespace. If we accept this argument, |
| the consequence is that standard library functions should use |
| unqualified call of <tt>swap</tt>. (And which other functions? Any?) |
| A small group (Nathan, Howard, Jeremy, Dave, Matt, Walter, Marc) will |
| try to put together a proposal before the next meeting.]</i></p> |
| |
| <p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues |
| 225, 226, and 229. Their conclusion was that the issues should be |
| separated into an LWG portion (Howard's paper, N1387=02-0045), and a |
| EWG portion (Dave will write a proposal). The LWG and EWG had |
| (separate) discussions of this plan the next day. The proposed |
| resolution is the one proposed by Howard.]</i></p> |
| |
| <p><i>[Santa Cruz: the LWG agreed with the general direction of |
| Howard's paper, N1387. (Roughly: Koenig lookup is disabled unless |
| we say otherwise; this issue is about when we do say otherwise.) |
| However, there were concerns about wording. Howard will provide new |
| wording. Bill and Jeremy will review it.]</i></p> |
| |
| <p><i>[Kona: Howard proposed the new wording. The LWG accepted his |
| proposed resolution.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>Informally: introduce a Swappable concept, and specify that the |
| value types of the iterators passed to certain standard algorithms |
| (such as iter_swap, swap_ranges, reverse, rotate, and sort) conform |
| to that concept. The Swappable concept will make it clear that |
| these algorithms use unqualified lookup for the calls |
| to <tt>swap</tt>. Also, in <font color="red">26.3.3.3</font> paragraph 1, |
| state that the valarray transcendentals use unqualified lookup.</p> |
| <hr> |
| <a name="227"><h3>227. std::swap() should require CopyConstructible or DefaultConstructible arguments</h3></a><p><b>Section:</b> 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#TC">TC</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 09 Apr 2000</p> |
| <p>25.2.2 reads:</p> |
| <blockquote> |
| <p><tt> template<class T> void swap(T& a, T& b);</tt><br> |
| <br> |
| Requires: Type T is Assignable (_lib.container.requirements_).<br> |
| Effects: Exchanges values stored in two locations.</p> |
| </blockquote> |
| <p>The only reasonable** generic implementation of swap requires construction of a |
| new temporary copy of one of its arguments:</p> |
| <blockquote> |
| <pre>template<class T> void swap(T& a, T& b); |
| { |
| T tmp(a); |
| a = b; |
| b = tmp; |
| }</pre> |
| </blockquote> |
| <p>But a type which is only Assignable cannot be swapped by this implementation.</p> |
| <p>**Yes, there's also an unreasonable implementation which would require T to be |
| DefaultConstructible instead of CopyConstructible. I don't think this is worthy |
| of consideration:</p> |
| <blockquote> |
| <pre>template<class T> void swap(T& a, T& b); |
| { |
| T tmp; |
| tmp = a; |
| a = b; |
| b = tmp; |
| }</pre> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.2.2 paragraph 1 from:</p> |
| <blockquote> |
| <p> Requires: Type T is Assignable (23.1).</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p> Requires: Type T is CopyConstructible (20.1.3) and Assignable (23.1)</p> |
| </blockquote> |
| <hr> |
| <a name="228"><h3>228. Incorrect specification of "..._byname" facets</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#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Apr 2000</p> |
| <p>The sections 22.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.ctype.byname"> [lib.locale.ctype.byname]</a>, 22.2.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.codecvt"> [lib.locale.codecvt]</a>, |
| <font color="red">22.2.1.6</font>, 22.2.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.numpunct.byname"> [lib.locale.numpunct.byname]</a>, 22.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.collate.byname"> [lib.locale.collate.byname]</a>, 22.2.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.put.byname"> [lib.locale.time.put.byname]</a>, 22.2.6.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.moneypunct.byname"> [lib.locale.moneypunct.byname]</a>, and 22.2.7.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.messages.byname"> [lib.locale.messages.byname]</a> overspecify the |
| definitions of the "..._byname" classes by listing a bunch |
| of virtual functions. At the same time, no semantics of these |
| functions are defined. Real implementations do not define these |
| functions because the functional part of the facets is actually |
| implemented in the corresponding base classes and the constructor of |
| the "..._byname" version just provides suitable date used by |
| these implementations. For example, the 'numpunct' methods just return |
| values from a struct. The base class uses a statically initialized |
| struct while the derived version reads the contents of this struct |
| from a table. However, no virtual function is defined in |
| 'numpunct_byname'.</p> |
| |
| <p>For most classes this does not impose a problem but specifically |
| for 'ctype' it does: The specialization for 'ctype_byname<char>' |
| is required because otherwise the semantics would change due to the |
| virtual functions defined in the general version for 'ctype_byname': |
| In 'ctype<char>' the method 'do_is()' is not virtual but it is |
| made virtual in both 'ctype<cT>' and 'ctype_byname<cT>'. |
| Thus, a class derived from 'ctype_byname<char>' can tell whether |
| this class is specialized or not under the current specification: |
| Without the specialization, 'do_is()' is virtual while with |
| specialization it is not virtual.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p> Change section 22.2.1.2 (lib.locale.ctype.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class ctype_byname : public ctype<charT> { |
| public: |
| typedef ctype<charT>::mask mask; |
| explicit ctype_byname(const char*, size_t refs = 0); |
| protected: |
| ~ctype_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.1.6 (lib.locale.codecvt.byname) to become:</p> |
| <pre> namespace std { |
| template <class internT, class externT, class stateT> |
| class codecvt_byname : public codecvt<internT, externT, stateT> { |
| public: |
| explicit codecvt_byname(const char*, size_t refs = 0); |
| protected: |
| ~codecvt_byname(); // virtual |
| }; |
| } |
| </pre> |
| <p> Change section 22.2.3.2 (lib.locale.numpunct.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class numpunct_byname : public numpunct<charT> { |
| // this class is specialized for char and wchar_t. |
| public: |
| typedef charT char_type; |
| typedef basic_string<charT> string_type; |
| explicit numpunct_byname(const char*, size_t refs = 0); |
| protected: |
| ~numpunct_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.4.2 (lib.locale.collate.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class collate_byname : public collate<charT> { |
| public: |
| typedef basic_string<charT> string_type; |
| explicit collate_byname(const char*, size_t refs = 0); |
| protected: |
| ~collate_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.5.2 (lib.locale.time.get.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT, class InputIterator = istreambuf_iterator<charT> > |
| class time_get_byname : public time_get<charT, InputIterator> { |
| public: |
| typedef time_base::dateorder dateorder; |
| typedef InputIterator iter_type</pre> |
| <pre> explicit time_get_byname(const char*, size_t refs = 0); |
| protected: |
| ~time_get_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.5.4 (lib.locale.time.put.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT, class OutputIterator = ostreambuf_iterator<charT> > |
| class time_put_byname : public time_put<charT, OutputIterator> |
| { |
| public: |
| typedef charT char_type; |
| typedef OutputIterator iter_type;</pre> |
| <pre> explicit time_put_byname(const char*, size_t refs = 0); |
| protected: |
| ~time_put_byname(); // virtual |
| }; |
| }"</pre> |
| <p> Change section 22.2.6.4 (lib.locale.moneypunct.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT, bool Intl = false> |
| class moneypunct_byname : public moneypunct<charT, Intl> { |
| public: |
| typedef money_base::pattern pattern; |
| typedef basic_string<charT> string_type;</pre> |
| <pre> explicit moneypunct_byname(const char*, size_t refs = 0); |
| protected: |
| ~moneypunct_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.7.2 (lib.locale.messages.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class messages_byname : public messages<charT> { |
| public: |
| typedef messages_base::catalog catalog; |
| typedef basic_string<charT> string_type;</pre> |
| <pre> explicit messages_byname(const char*, size_t refs = 0); |
| protected: |
| ~messages_byname(); // virtual |
| }; |
| }</pre> |
| <p>Remove section 22.2.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.codecvt"> [lib.locale.codecvt]</a> completely (because in |
| this case only those members are defined to be virtual which are |
| defined to be virtual in 'ctype<cT>'.)</p> |
| |
| <p><i>[Post-Tokyo: Dietmar Kühl submitted this issue at the request of |
| the LWG to solve the underlying problems raised by issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#138">138</a>.]</i></p> |
| |
| <p><i>[Copenhagen: proposed resolution was revised slightly, to remove |
| three last virtual functions from <tt>messages_byname</tt>.]</i></p> |
| |
| <hr> |
| <a name="229"><h3>229. Unqualified references of other library entities</h3></a><p><b>Section:</b> 17.4.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.contents"> [lib.contents]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 19 Apr 2000</p> |
| <p>Throughout the library chapters, the descriptions of library entities refer |
| to other library entities without necessarily qualifying the names.</p> |
| |
| <p>For example, section 25.2.2 "Swap" describes the effect of |
| swap_ranges in terms of the unqualified name "swap". This section |
| could reasonably be interpreted to mean that the library must be implemented so |
| as to do a lookup of the unqualified name "swap", allowing users to |
| override any ::std::swap function when Koenig lookup applies.</p> |
| |
| <p>Although it would have been best to use explicit qualification with |
| "::std::" throughout, too many lines in the standard would have to be |
| adjusted to make that change in a Technical Corrigendum.</p> |
| |
| <p>Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#182">182</a>, which addresses qualification of |
| <tt>size_t</tt>, is a special case of this. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>To section 17.4.1.1 "Library contents" Add the following paragraph:</p> |
| <blockquote> |
| <p>Whenever a name x defined in the standard library is mentioned, the name x |
| is assumed to be fully qualified as ::std::x, unless explicitly described |
| otherwise. For example, if the Effects section for library function F is |
| described as calling library function G, the function ::std::G is meant.</p> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: Steve Clamage submitted this issue at the request of |
| the LWG to solve a problem in the standard itself similar to the |
| problem within implementations of library identified by issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a>. Any resolution of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a> should be |
| coordinated with the resolution of this issue.]</i></p> |
| |
| <p><i>[post-Toronto: Howard is undecided about whether it is |
| appropriate for all standard library function names referred to in |
| other standard library functions to be explicitly qualified by |
| <tt>std</tt>: it is common advice that users should define global |
| functions that operate on their class in the same namespace as the |
| class, and this requires argument-dependent lookup if those functions |
| are intended to be called by library code. Several LWG members are |
| concerned that valarray appears to require argument-dependent lookup, |
| but that the wording may not be clear enough to fall under |
| "unless explicitly described otherwise".]</i></p> |
| |
| <p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues |
| 225, 226, and 229. Their conclusion was that the issues should be |
| separated into an LWG portion (Howard's paper, N1387=02-0045), and a |
| EWG portion (Dave will write a proposal). The LWG and EWG had |
| (separate) discussions of this plan the next day. This paper resolves |
| issues 225 and 226. In light of that resolution, the proposed |
| resolution for the current issue makes sense.]</i></p> |
| |
| <hr> |
| <a name="230"><h3>230. Assignable specified without also specifying CopyConstructible</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#WP">WP</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 26 Apr 2000</p> |
| <p>Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#227">227</a> identified an instance (std::swap) where |
| Assignable was specified without also specifying |
| CopyConstructible. The LWG asked that the standard be searched to |
| determine if the same defect existed elsewhere.</p> |
| |
| <p>There are a number of places (see proposed resolution below) where |
| Assignable is specified without also specifying |
| CopyConstructible. There are also several cases where both are |
| specified. For example, 26.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.rand.req"> [lib.rand.req]</a>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> table 65 for value_type: |
| change "T is Assignable" to "T is CopyConstructible and |
| Assignable" |
| </p> |
| |
| <p>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> table 69 X::key_type; change |
| "Key is Assignable" to "Key is |
| CopyConstructible and Assignable"<br> |
| </p> |
| |
| <p>In 24.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.output.iterators"> [lib.output.iterators]</a> paragraph 1, change: |
| </p> |
| <blockquote> |
| <p> A class or a built-in type X satisfies the requirements of an |
| output iterator if X is an Assignable type (23.1) and also the |
| following expressions are valid, as shown in Table 73: |
| </p> |
| </blockquote> |
| <p>to: |
| </p> |
| <blockquote> |
| <p> A class or a built-in type X satisfies the requirements of an |
| output iterator if X is a CopyConstructible (20.1.3) and Assignable |
| type (23.1) and also the following expressions are valid, as shown in |
| Table 73: |
| </p> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: Beman Dawes submitted this issue at the request of |
| the LWG. He asks that the 25.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a> and 25.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.fill"> [lib.alg.fill]</a> changes be studied carefully, as it is not clear that |
| CopyConstructible is really a requirement and may be |
| overspecification.]</i></p> |
| |
| <p><i>[Portions of the resolution for issue 230 have been superceded by |
| the resolution of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#276">276</a>.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution also included changes to input |
| iterator, fill, and replace. The LWG believes that those changes are |
| not necessary. The LWG considered some blanket statement, where an |
| Assignable type was also required to be Copy Constructible, but |
| decided against this because fill and replace really don't require the |
| Copy Constructible property.</p> |
| <hr> |
| <a name="231"><h3>231. Precision in iostream?</h3></a><p><b>Section:</b> 22.2.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> James Kanze, Stephen Clamage <b>Date:</b> 25 Apr 2000</p> |
| <p>What is the following program supposed to output?</p> |
| <pre>#include <iostream> |
| |
| int |
| main() |
| { |
| std::cout.setf( std::ios::scientific , std::ios::floatfield ) ; |
| std::cout.precision( 0 ) ; |
| std::cout << 1.00 << '\n' ; |
| return 0 ; |
| }</pre> |
| <p>From my C experience, I would expect "1e+00"; this is what |
| <tt>printf("%.0e" , 1.00 );</tt> does. G++ outputs |
| "1.000000e+00".</p> |
| |
| <p>The only indication I can find in the standard is 22.2.2.2.2/11, |
| where it says "For conversion from a floating-point type, if |
| (flags & fixed) != 0 or if str.precision() > 0, then |
| str.precision() is specified in the conversion specification." |
| This is an obvious error, however, fixed is not a mask for a field, |
| but a value that a multi-bit field may take -- the results of and'ing |
| fmtflags with ios::fixed are not defined, at least not if |
| ios::scientific has been set. G++'s behavior corresponds to what might |
| happen if you do use (flags & fixed) != 0 with a typical |
| implementation (floatfield == 3 << something, fixed == 1 |
| << something, and scientific == 2 << something).</p> |
| |
| <p>Presumably, the intent is either (flags & floatfield) != 0, or |
| (flags & floatfield) == fixed; the first gives something more or |
| less like the effect of precision in a printf floating point |
| conversion. Only more or less, of course. In order to implement printf |
| formatting correctly, you must know whether the precision was |
| explicitly set or not. Say by initializing it to -1, instead of 6, and |
| stating that for floating point conversions, if precision < -1, 6 |
| will be used, for fixed point, if precision < -1, 1 will be used, |
| etc. Plus, of course, if precision == 0 and flags & floatfield == |
| 0, 1 should be = used. But it probably isn't necessary to emulate all |
| of the anomalies of printf:-).</p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace 22.2.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a>, paragraph 11, with the following |
| sentence: |
| </p> |
| <blockquote> |
| For conversion from a floating-point type, |
| <tt><i>str</i>.precision()</tt> is specified in the conversion |
| specification. |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The floatfield determines whether numbers are formatted as if |
| with %f, %e, or %g. If the <tt>fixed</tt> bit is set, it's %f, |
| if <tt>scientific</tt> it's %e, and if both bits are set, or |
| neither, it's %g.</p> |
| <p>Turning to the C standard, a precision of 0 is meaningful |
| for %f and %e. For %g, precision 0 is taken to be the same as |
| precision 1.</p> |
| <p>The proposed resolution has the effect that if neither |
| <tt>fixed</tt> nor <tt>scientific</tt> is set we'll be |
| specifying a precision of 0, which will be internally |
| turned into 1. There's no need to call it out as a special |
| case.</p> |
| <p>The output of the above program will be "1e+00".</p> |
| |
| <p><i>[Post-Curaçao: Howard provided improved wording covering the case |
| where precision is 0 and mode is %g.]</i></p> |
| |
| <hr> |
| <a name="232"><h3>232. "depends" poorly defined in 17.4.3.1</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#WP">WP</a> <b>Submitter:</b> Peter Dimov <b>Date:</b> 18 Apr 2000</p> |
| <p>17.4.3.1/1 uses the term "depends" to limit the set of allowed |
| specializations of standard templates to those that "depend on a |
| user-defined name of external linkage."</p> |
| <p>This term, however, is not adequately defined, making it possible to |
| construct a specialization that is, I believe, technically legal according to |
| 17.4.3.1/1, but that specializes a standard template for a built-in type such as |
| 'int'.</p> |
| <p>The following code demonstrates the problem:</p> |
| <blockquote> |
| <pre>#include <algorithm></pre> |
| <pre>template<class T> struct X |
| { |
| typedef T type; |
| };</pre> |
| <pre>namespace std |
| { |
| template<> void swap(::X<int>::type& i, ::X<int>::type& j); |
| }</pre> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change "user-defined name" to "user-defined |
| type".</p> |
| <p><b>Rationale:</b></p> |
| <p>This terminology is used in section 2.5.2 and 4.1.1 of <i>The C++ |
| Programming Language</i>. It disallows the example in the issue, |
| since the underlying type itself is not user-defined. The only |
| possible problem I can see is for non-type templates, but there's no |
| possible way for a user to come up with a specialization for bitset, |
| for example, that might not have already been specialized by the |
| implementor?</p> |
| |
| <p><i>[Toronto: this may be related to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#120">120</a>.]</i></p> |
| |
| <p><i>[post-Toronto: Judy provided the above proposed resolution and |
| rationale.]</i></p> |
| <hr> |
| <a name="234"><h3>234. Typos in allocator definition</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#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 24 Apr 2000</p> |
| <p>In paragraphs 12 and 13 the effects of <tt>construct()</tt> and |
| <tt>destruct()</tt> are described as returns but the functions actually |
| return <tt>void</tt>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Substitute "Returns" by "Effect".</p> |
| <hr> |
| <a name="235"><h3>235. No specification of default ctor for reverse_iterator</h3></a><p><b>Section:</b> 24.4.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iterator"> [lib.reverse.iterator]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 24 Apr 2000</p> |
| <p>The declaration of <tt>reverse_iterator</tt> lists a default |
| constructor. However, no specification is given what this constructor |
| should do.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In section 24.4.1.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.cons"> [lib.reverse.iter.cons]</a> add the following |
| paragraph:</p> |
| <blockquote> |
| <p><tt>reverse_iterator()</tt></p> |
| |
| <p>Default initializes <tt>current</tt>. Iterator operations |
| applied to the resulting iterator have defined behavior if and |
| only if the corresponding operations are defined on a default |
| constructed iterator of type <tt>Iterator</tt>.</p> |
| </blockquote> |
| <p><i>[pre-Copenhagen: Dietmar provide wording for proposed |
| resolution.]</i></p> |
| <hr> |
| <a name="237"><h3>237. Undefined expression in complexity specification</h3></a><p><b>Section:</b> 23.2.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.cons"> [lib.deque.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 24 Apr 2000</p> |
| <p>The complexity specification in paragraph 6 says that the complexity |
| is linear in <tt>first - last</tt>. Even if <tt>operator-()</tt> is |
| defined on iterators this term is in general undefined because it |
| would have to be <tt>last - first</tt>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change paragraph 6 from</p> |
| <blockquote>Linear in <i>first - last</i>.</blockquote> |
| <p>to become</p> |
| <blockquote>Linear in <i>distance(first, last)</i>.</blockquote> |
| <hr> |
| <a name="238"><h3>238. Contradictory results of stringbuf initialization.</h3></a><p><b>Section:</b> 27.7.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf.cons"> [lib.stringbuf.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 11 May 2000</p> |
| <p>In 27.7.1.1 paragraph 4 the results of calling the constructor of |
| 'basic_stringbuf' are said to be <tt>str() == str</tt>. This is fine |
| that far but consider this code:</p> |
| |
| <pre> std::basic_stringbuf<char> sbuf("hello, world", std::ios_base::openmode(0)); |
| std::cout << "'" << sbuf.str() << "'\n"; |
| </pre> |
| |
| <p>Paragraph 3 of 27.7.1.1 basically says that in this case neither |
| the output sequence nor the input sequence is initialized and |
| paragraph 2 of 27.7.1.2 basically says that <tt>str()</tt> either |
| returns the input or the output sequence. None of them is initialized, |
| ie. both are empty, in which case the return from <tt>str()</tt> is |
| defined to be <tt>basic_string<cT>()</tt>.</p> |
| |
| <p>However, probably only test cases in some testsuites will detect this |
| "problem"...</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove 27.7.1.1 paragraph 4.</p> |
| <p><b>Rationale:</b></p> |
| <p>We could fix 27.7.1.1 paragraph 4, but there would be no point. If |
| we fixed it, it would say just the same thing as text that's already |
| in the standard.</p> |
| <hr> |
| <a name="239"><h3>239. Complexity of unique() and/or unique_copy incorrect</h3></a><p><b>Section:</b> 25.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> May 15 2000</p> |
| <p>The complexity of unique and unique_copy are inconsistent with each |
| other and inconsistent with the implementations. The standard |
| specifies:</p> |
| |
| <p>for unique():</p> |
| |
| <blockquote>-3- Complexity: If the range (last - first) is not empty, exactly |
| (last - first) - 1 applications of the corresponding predicate, otherwise |
| no applications of the predicate.</blockquote> |
| |
| <p>for unique_copy():</p> |
| |
| <blockquote>-7- Complexity: Exactly last - first applications of the corresponding |
| predicate.</blockquote> |
| |
| <p> |
| The implementations do it the other way round: unique() applies the |
| predicate last-first times and unique_copy() applies it last-first-1 |
| times.</p> |
| |
| <p>As both algorithms use the predicate for pair-wise comparison of |
| sequence elements I don't see a justification for unique_copy() |
| applying the predicate last-first times, especially since it is not |
| specified to which pair in the sequence the predicate is applied |
| twice.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change both complexity sections in 25.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> to:</p> |
| |
| <blockquote>Complexity: For nonempty ranges, exactly last - first - 1 |
| applications of the corresponding predicate.</blockquote> |
| |
| <hr> |
| <a name="240"><h3>240. Complexity of adjacent_find() is meaningless</h3></a><p><b>Section:</b> 25.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.adjacent.find"> [lib.alg.adjacent.find]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> May 15 2000</p> |
| <p>The complexity section of adjacent_find is defective:</p> |
| |
| <blockquote> |
| <pre>template <class ForwardIterator> |
| ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last |
| BinaryPredicate pred); |
| </pre> |
| |
| <p>-1- Returns: The first iterator i such that both i and i + 1 are in |
| the range [first, last) for which the following corresponding |
| conditions hold: *i == *(i + 1), pred(*i, *(i + 1)) != false. Returns |
| last if no such iterator is found.</p> |
| |
| <p>-2- Complexity: Exactly find(first, last, value) - first applications |
| of the corresponding predicate. |
| </p> |
| </blockquote> |
| |
| <p>In the Complexity section, it is not defined what "value" |
| is supposed to mean. My best guess is that "value" means an |
| object for which one of the conditions pred(*i,value) or |
| pred(value,*i) is true, where i is the iterator defined in the Returns |
| section. However, the value type of the input sequence need not be |
| equality-comparable and for this reason the term find(first, last, |
| value) - first is meaningless.</p> |
| |
| <p>A term such as find_if(first, last, bind2nd(pred,*i)) - first or |
| find_if(first, last, bind1st(pred,*i)) - first might come closer to |
| the intended specification. Binders can only be applied to function |
| objects that have the function call operator declared const, which is |
| not required of predicates because they can have non-const data |
| members. For this reason, a specification using a binder could only be |
| an "as-if" specification.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the complexity section in 25.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.adjacent.find"> [lib.alg.adjacent.find]</a> to:</p> |
| <blockquote> |
| For a nonempty range, exactly <tt>min((<i>i</i> - <i>first</i>) + 1, |
| (<i>last</i> - <i>first</i>) - 1)</tt> applications of the |
| corresponding predicate, where <i>i</i> is <tt>adjacent_find</tt>'s |
| return value. |
| </blockquote> |
| |
| <p><i>[Copenhagen: the original resolution specified an upper |
| bound. The LWG preferred an exact count.]</i></p> |
| |
| <hr> |
| <a name="241"><h3>241. Does unique_copy() require CopyConstructible and Assignable?</h3></a><p><b>Section:</b> 25.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> May 15 2000</p> |
| |
| <p>Some popular implementations of unique_copy() create temporary |
| copies of values in the input sequence, at least if the input iterator |
| is a pointer. Such an implementation is built on the assumption that |
| the value type is CopyConstructible and Assignable.</p> |
| |
| <p>It is common practice in the standard that algorithms explicitly |
| specify any additional requirements that they impose on any of the |
| types used by the algorithm. An example of an algorithm that creates |
| temporary copies and correctly specifies the additional requirements |
| is accumulate(), 26.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.rand.req"> [lib.rand.req]</a>.</p> |
| |
| <p>Since the specifications of unique() and unique_copy() do not |
| require CopyConstructible and Assignable of the InputIterator's value |
| type the above mentioned implementations are not standard-compliant. I |
| cannot judge whether this is a defect in the standard or a defect in |
| the implementations.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.2.8 change:</p> |
| |
| <blockquote> |
| -4- Requires: The ranges [first, last) and [result, result+(last-first)) |
| shall not overlap. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>-4- Requires: The ranges [first, last) and [result, |
| result+(last-first)) shall not overlap. The expression *result = |
| *first must be valid. If neither InputIterator nor OutputIterator |
| meets the requirements of forward iterator then the value type of |
| InputIterator must be copy constructible. Otherwise copy |
| constructible is not required. </p> |
| </blockquote> |
| |
| <p><i>[Redmond: the original proposed resolution didn't impose an |
| explicit requirement that the iterator's value type must be copy |
| constructible, on the grounds that an input iterator's value type must |
| always be copy constructible. Not everyone in the LWG thought that |
| this requirement was clear from table 72. It has been suggested that |
| it might be possible to implement <tt>unique_copy</tt> without |
| requiring assignability, although current implementations do impose |
| that requirement. Howard provided new wording.]</i></p> |
| |
| <p><i>[ |
| Curaçao: The LWG changed the PR editorially to specify |
| "neither...nor...meet..." as clearer than |
| "both...and...do not meet...". Change believed to be so |
| minor as not to require re-review. |
| ]</i></p> |
| |
| <hr> |
| <a name="242"><h3>242. Side effects of function objects</h3></a><p><b>Section:</b> 25.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.transform"> [lib.alg.transform]</a>, 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#WP">WP</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> May 15 2000</p> |
| <p>The algorithms transform(), accumulate(), inner_product(), |
| partial_sum(), and adjacent_difference() require that the function |
| object supplied to them shall not have any side effects.</p> |
| |
| <p>The standard defines a side effect in 1.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/intro.html#intro.execution"> [intro.execution]</a> as:</p> |
| <blockquote>-7- Accessing an object designated by a volatile lvalue (basic.lval), |
| modifying an object, calling a library I/O function, or calling a function |
| that does any of those operations are all side effects, which are changes |
| in the state of the execution environment.</blockquote> |
| |
| <p>As a consequence, the function call operator of a function object supplied |
| to any of the algorithms listed above cannot modify data members, cannot |
| invoke any function that has a side effect, and cannot even create and |
| modify temporary objects. It is difficult to imagine a function object |
| that is still useful under these severe limitations. For instance, any |
| non-trivial transformator supplied to transform() might involve creation |
| and modification of temporaries, which is prohibited according to the current |
| wording of the standard.</p> |
| |
| <p>On the other hand, popular implementations of these algorithms exhibit |
| uniform and predictable behavior when invoked with a side-effect-producing |
| function objects. It looks like the strong requirement is not needed for |
| efficient implementation of these algorithms.</p> |
| |
| <p>The requirement of side-effect-free function objects could be |
| replaced by a more relaxed basic requirement (which would hold for all |
| function objects supplied to any algorithm in the standard library):</p> |
| <blockquote>A function objects supplied to an algorithm shall not invalidate |
| any iterator or sequence that is used by the algorithm. Invalidation of |
| the sequence includes destruction of the sorting order if the algorithm |
| relies on the sorting order (see section 25.3 - Sorting and related operations |
| [lib.alg.sorting]).</blockquote> |
| |
| <p>I can't judge whether it is intended that the function objects supplied |
| to transform(), accumulate(), inner_product(), partial_sum(), or adjacent_difference() |
| shall not modify sequence elements through dereferenced iterators.</p> |
| |
| <p>It is debatable whether this issue is a defect or a change request. |
| Since the consequences for user-supplied function objects are drastic and |
| limit the usefulness of the algorithms significantly I would consider it |
| a defect.</p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>Things to notice about these changes:</i></p> |
| |
| <ol> |
| <li> <i>The fully-closed ("[]" as opposed to half-closed "[)" ranges |
| are intentional. we want to prevent side-effects from |
| invalidating the end iterators.</i> |
| </li> |
| |
| <li> <i>That has the unintentional side-effect of prohibiting |
| modification of the end element as a side-effect. This could |
| conceivably be significant in some cases.</i> |
| </li> |
| |
| <li> <i>The wording also prevents side-effects from modifying elements |
| of the output sequence. I can't imagine why anyone would want |
| to do this, but it is arguably a restriction that implementors |
| don't need to place on users.</i> |
| </li> |
| |
| <li> <i>Lifting the restrictions imposed in #2 and #3 above is possible |
| and simple, but would require more verbiage.</i> |
| </li> |
| </ol> |
| |
| <p>Change 25.2.3/2 from:</p> |
| |
| <blockquote> |
| -2- Requires: op and binary_op shall not have any side effects. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -2- Requires: in the ranges [first1, last1], [first2, first2 + |
| (last1 - first1)] and [result, result + (last1- first1)], op and |
| binary_op shall neither modify elements nor invalidate iterators or |
| subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </blockquote> |
| |
| |
| <p>Change 25.2.3/2 from:</p> |
| |
| <blockquote> |
| -2- Requires: op and binary_op shall not have any side effects. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -2- Requires: op and binary_op shall not invalidate iterators or |
| subranges, or modify elements in the ranges [first1, last1], |
| [first2, first2 + (last1 - first1)], and [result, result + (last1 |
| - first1)]. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </blockquote> |
| |
| |
| <p>Change 26.4.1/2 from:</p> |
| |
| <blockquote> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable (lib.container.requirements) |
| types. binary_op shall not cause side effects. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable |
| (lib.container.requirements) types. In the range [first, last], |
| binary_op shall neither modify elements nor invalidate iterators |
| or subranges. |
| [Footnote: The use of a fully closed range is intentional --end footnote] |
| </blockquote> |
| |
| <p>Change 26.4.2/2 from:</p> |
| |
| <blockquote> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable (lib.container.requirements) |
| types. binary_op1 and binary_op2 shall not cause side effects. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable (lib.container.requirements) |
| types. In the ranges [first, last] and [first2, first2 + (last - |
| first)], binary_op1 and binary_op2 shall neither modify elements |
| nor invalidate iterators or subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </blockquote> |
| |
| |
| <p>Change 26.4.3/4 from:</p> |
| |
| <blockquote> |
| -4- Requires: binary_op is expected not to have any side effects. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -4- Requires: In the ranges [first, last] and [result, result + |
| (last - first)], binary_op shall neither modify elements nor |
| invalidate iterators or subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </blockquote> |
| |
| <p>Change 26.4.4/2 from:</p> |
| |
| <blockquote> |
| -2- Requires: binary_op shall not have any side effects. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -2- Requires: In the ranges [first, last] and [result, result + |
| (last - first)], binary_op shall neither modify elements nor |
| invalidate iterators or subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </blockquote> |
| |
| <p><i>[Toronto: Dave Abrahams supplied wording.]</i></p> |
| |
| <p><i>[Copenhagen: Proposed resolution was modified slightly. Matt |
| added footnotes pointing out that the use of closed ranges was |
| intentional.]</i></p> |
| |
| <hr> |
| <a name="243"><h3>243. <tt>get</tt> and <tt>getline</tt> when sentry reports failure</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> May 15 2000</p> |
| <p>basic_istream<>::get(), and basic_istream<>::getline(), |
| are unclear with respect to the behavior and side-effects of the named |
| functions in case of an error.</p> |
| |
| <p>27.6.1.3, p1 states that "... If the sentry object returns |
| true, when converted to a value of type bool, the function endeavors |
| to obtain the requested input..." It is not clear from this (or |
| the rest of the paragraph) what precisely the behavior should be when |
| the sentry ctor exits by throwing an exception or when the sentry |
| object returns false. In particular, what is the number of characters |
| extracted that gcount() returns supposed to be?</p> |
| |
| <p>27.6.1.3 p8 and p19 say about the effects of get() and getline(): |
| "... In any case, it then stores a null character (using |
| charT()) into the next successive location of the array." Is not |
| clear whether this sentence applies if either of the conditions above |
| holds (i.e., when sentry fails).</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to 27.6.1.3, p1 after the sentence</p> |
| |
| <blockquote> |
| "... If the sentry object returns true, when converted to a value of |
| type bool, the function endeavors to obtain the requested input." |
| </blockquote> |
| |
| <p>the following</p> |
| |
| |
| <blockquote> |
| "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." |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Although the general philosophy of the input functions is that the |
| argument should not be modified upon failure, <tt>getline</tt> |
| historically added a terminating null unconditionally. Most |
| implementations still do that. Earlier versions of the draft standard |
| had language that made this an unambiguous requirement; those words |
| were moved to a place where their context made them less clear. See |
| Jerry Schwarz's message c++std-lib-7618.</p> |
| <hr> |
| <a name="247"><h3>247. <tt>vector</tt>, <tt>deque::insert</tt> complexity</h3></a><p><b>Section:</b> 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.stack"> [lib.stack]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Lisa Lippincott <b>Date:</b> 06 June 2000</p> |
| <p>Paragraph 2 of 23.2.4.3 [lib.vector.modifiers] describes the complexity |
| of <tt>vector::insert</tt>:</p> |
| |
| <blockquote> |
| Complexity: If first and last are forward iterators, bidirectional |
| iterators, or random access iterators, the complexity is linear in |
| the number of elements in the range [first, last) plus the distance |
| to the end of the vector. If they are input iterators, the complexity |
| is proportional to the number of elements in the range [first, last) |
| times the distance to the end of the vector. |
| </blockquote> |
| |
| <p>First, this fails to address the non-iterator forms of |
| <tt>insert</tt>.</p> |
| |
| <p>Second, the complexity for input iterators misses an edge case -- |
| it requires that an arbitrary number of elements can be added at |
| the end of a <tt>vector</tt> in constant time.</p> |
| |
| <p>I looked to see if <tt>deque</tt> had a similar problem, and was |
| surprised to find that <tt>deque</tt> places no requirement on the |
| complexity of inserting multiple elements (23.2.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.array.size"> [lib.array.size]</a>, |
| paragraph 3):</p> |
| |
| <blockquote> |
| Complexity: In the worst case, inserting a single element into a |
| deque takes time linear in the minimum of the distance from the |
| insertion point to the beginning of the deque and the distance |
| from the insertion point to the end of the deque. Inserting a |
| single element either at the beginning or end of a deque always |
| takes constant time and causes a single call to the copy constructor |
| of T. |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change Paragraph 2 of 23.2.4.3 [lib.vector.modifiers] to</p> |
| <blockquote> |
| Complexity: The complexity is linear in the number of elements |
| inserted plus the distance to the end of the vector. |
| </blockquote> |
| |
| <p><i>[For input iterators, one may achieve this complexity by first |
| inserting at the end of the <tt>vector</tt>, and then using |
| <tt>rotate</tt>.]</i></p> |
| |
| <p>Change 23.2.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.array.size"> [lib.array.size]</a>, paragraph 3, to:</p> |
| |
| <blockquote> |
| Complexity: The complexity is linear in the number of elements |
| inserted plus the shorter of the distances to the beginning and |
| end of the deque. Inserting a single element at either the |
| beginning or the end of a deque causes a single call to the copy |
| constructor of T. |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p>This is a real defect, and proposed resolution fixes it: some |
| complexities aren't specified that should be. This proposed |
| resolution does constrain deque implementations (it rules out the |
| most naive possible implementations), but the LWG doesn't see a |
| reason to permit that implementation.</p> |
| <hr> |
| <a name="248"><h3>248. time_get fails to set eofbit</h3></a><p><b>Section:</b> 22.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.category.time"> [lib.category.time]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 22 June 2000</p> |
| <p>There is no requirement that any of time_get member functions set |
| ios::eofbit when they reach the end iterator while parsing their input. |
| Since members of both the num_get and money_get facets are required to |
| do so (22.2.2.1.2, and 22.2.6.1.2, respectively), time_get members |
| should follow the same requirement for consistency.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add paragraph 2 to section 22.2.5.1 with the following text:</p> |
| |
| <blockquote> |
| If the end iterator is reached during parsing by any of the get() |
| member functions, the member sets ios_base::eofbit in err. |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Two alternative resolutions were proposed. The LWG chose this one |
| because it was more consistent with the way eof is described for other |
| input facets.</p> |
| <hr> |
| <a name="250"><h3>250. splicing invalidates iterators</h3></a><p><b>Section:</b> 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Brian Parker <b>Date:</b> 14 Jul 2000</p> |
| <p> |
| Section 23.2.2.4 [lib.list.ops] states that |
| </p> |
| <pre> void splice(iterator position, list<T, Allocator>& x); |
| </pre> |
| <p> |
| <i>invalidates</i> all iterators and references to list <tt>x</tt>. |
| </p> |
| |
| <p> |
| This is unnecessary and defeats an important feature of splice. In |
| fact, the SGI STL guarantees that iterators to <tt>x</tt> remain valid |
| after <tt>splice</tt>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add a footnote to 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a>, paragraph 1:</p> |
| <blockquote> |
| [<i>Footnote:</i> As specified in 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>, paragraphs |
| 4-5, the semantics described in this clause applies only to the case |
| where allocators compare equal. --end footnote] |
| </blockquote> |
| |
| <p>In 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a>, replace paragraph 4 with:</p> |
| <blockquote> |
| Effects: Inserts the contents of x before position and x becomes |
| empty. Pointers and references to the moved elements of x now refer to |
| those same elements but as members of *this. Iterators referring to the |
| moved elements will continue to refer to their elements, but they now |
| behave as iterators into *this, not into x. |
| </blockquote> |
| |
| <p>In 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a>, replace paragraph 7 with:</p> |
| <blockquote> |
| Effects: Inserts an element pointed to by i from list x before |
| position and removes the element from x. The result is unchanged if |
| position == i or position == ++i. Pointers and references to *i continue |
| to refer to this same element but as a member of *this. Iterators to *i |
| (including i itself) continue to refer to the same element, but now |
| behave as iterators into *this, not into x. |
| </blockquote> |
| |
| <p>In 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a>, replace paragraph 12 with:</p> |
| <blockquote> |
| Requires: [first, last) is a valid range in x. The result is |
| undefined if position is an iterator in the range [first, last). |
| Pointers and references to the moved elements of x now refer to those |
| same elements but as members of *this. Iterators referring to the moved |
| elements will continue to refer to their elements, but they now behave as |
| iterators into *this, not into x. |
| </blockquote> |
| |
| <p><i>[pre-Copenhagen: Howard provided wording.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution said that iterators and references |
| would remain "valid". The new proposed resolution clarifies what that |
| means. Note that this only applies to the case of equal allocators. |
| From 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, the behavior of list when |
| allocators compare nonequal is outside the scope of the standard.</p> |
| <hr> |
| <a name="251"><h3>251. basic_stringbuf missing allocator_type</h3></a><p><b>Section:</b> 27.7.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf"> [lib.stringbuf]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 Jul 2000</p> |
| <p>The synopsis for the template class <tt>basic_stringbuf</tt> |
| doesn't list a typedef for the template parameter |
| <tt>Allocator</tt>. This makes it impossible to determine the type of |
| the allocator at compile time. It's also inconsistent with all other |
| template classes in the library that do provide a typedef for the |
| <tt>Allocator</tt> parameter.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to the synopses of the class templates basic_stringbuf (27.7.1), |
| basic_istringstream (27.7.2), basic_ostringstream (27.7.3), and |
| basic_stringstream (27.7.4) the typedef:</p> |
| <pre> typedef Allocator allocator_type; |
| </pre> |
| <hr> |
| <a name="252"><h3>252. missing casts/C-style casts used in iostreams</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 Jul 2000</p> |
| <p>27.7.2.2, p1 uses a C-style cast rather than the more appropriate |
| const_cast<> in the Returns clause for basic_istringstream<>::rdbuf(). |
| The same C-style cast is being used in 27.7.3.2, p1, D.7.2.2, p1, and |
| D.7.3.2, p1, and perhaps elsewhere. 27.7.6, p1 and D.7.2.2, p1 are missing |
| the cast altogether.</p> |
| |
| <p>C-style casts have not been deprecated, so the first part of this |
| issue is stylistic rather than a matter of correctness.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.7.2.2, p1 replace </p> |
| <pre> -1- Returns: (basic_stringbuf<charT,traits,Allocator>*)&sb.</pre> |
| |
| <p>with</p> |
| <pre> -1- Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).</pre> |
| |
| |
| <p>In 27.7.3.2, p1 replace</p> |
| <pre> -1- Returns: (basic_stringbuf<charT,traits,Allocator>*)&sb.</pre> |
| |
| <p>with</p> |
| <pre> -1- Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).</pre> |
| |
| <p>In 27.7.6, p1, replace</p> |
| <pre> -1- Returns: &sb</pre> |
| |
| <p>with</p> |
| <pre> -1- Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).</pre> |
| |
| <p>In D.7.2.2, p1 replace</p> |
| <pre> -2- Returns: &sb. </pre> |
| |
| <p>with</p> |
| <pre> -2- Returns: const_cast<strstreambuf*>(&sb).</pre> |
| <hr> |
| <a name="253"><h3>253. valarray helper functions are almost entirely useless</h3></a><p><b>Section:</b> 26.5.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.valarray.cons"> [lib.valarray.cons]</a>, 26.5.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.valarray.assign"> [lib.valarray.assign]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Robert Klarer <b>Date:</b> 31 Jul 2000</p> |
| <p>This discussion is adapted from message c++std-lib-7056 posted |
| November 11, 1999. I don't think that anyone can reasonably claim |
| that the problem described below is NAD.</p> |
| |
| <p>These valarray constructors can never be called:</p> |
| |
| <pre> template <class T> |
| valarray<T>::valarray(const slice_array<T> &); |
| template <class T> |
| valarray<T>::valarray(const gslice_array<T> &); |
| template <class T> |
| valarray<T>::valarray(const mask_array<T> &); |
| template <class T> |
| valarray<T>::valarray(const indirect_array<T> &); |
| </pre> |
| |
| <p>Similarly, these valarray assignment operators cannot be |
| called:</p> |
| |
| <pre> template <class T> |
| valarray<T> valarray<T>::operator=(const slice_array<T> &); |
| template <class T> |
| valarray<T> valarray<T>::operator=(const gslice_array<T> &); |
| template <class T> |
| valarray<T> valarray<T>::operator=(const mask_array<T> &); |
| template <class T> |
| valarray<T> valarray<T>::operator=(const indirect_array<T> &); |
| </pre> |
| |
| <p>Please consider the following example:</p> |
| |
| <pre> #include <valarray> |
| using namespace std; |
| |
| int main() |
| { |
| valarray<double> va1(12); |
| valarray<double> va2(va1[slice(1,4,3)]); // line 1 |
| } |
| </pre> |
| |
| |
| <p>Since the valarray va1 is non-const, the result of the sub-expression |
| va1[slice(1,4,3)] at line 1 is an rvalue of type const |
| std::slice_array<double>. This slice_array rvalue is then used to |
| construct va2. The constructor that is used to construct va2 is |
| declared like this:</p> |
| |
| <pre> template <class T> |
| valarray<T>::valarray(const slice_array<T> &); |
| </pre> |
| |
| <p>Notice the constructor's const reference parameter. When the |
| constructor is called, a slice_array must be bound to this reference. |
| The rules for binding an rvalue to a const reference are in 8.5.3, |
| paragraph 5 (see also 13.3.3.1.4). Specifically, paragraph 5 |
| indicates that a second slice_array rvalue is constructed (in this |
| case copy-constructed) from the first one; it is this second rvalue |
| that is bound to the reference parameter. Paragraph 5 also requires |
| that the constructor that is used for this purpose be callable, |
| regardless of whether the second rvalue is elided. The |
| copy-constructor in this case is not callable, however, because it is |
| private. Therefore, the compiler should report an error.</p> |
| |
| <p>Since slice_arrays are always rvalues, the valarray constructor that has a |
| parameter of type const slice_array<T> & can never be called. The |
| same reasoning applies to the three other constructors and the four |
| assignment operators that are listed at the beginning of this post. |
| Furthermore, since these functions cannot be called, the valarray helper |
| classes are almost entirely useless.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>slice_array:</p> |
| <ul> |
| <li> Make the copy constructor and copy-assignment operator declarations |
| public in the slice_array class template definition in 26.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.slice.array"> [lib.template.slice.array]</a> </li> |
| <li> remove paragraph 3 of 26.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.slice.array"> [lib.template.slice.array]</a> |
| </li> |
| <li> remove the copy constructor declaration from 26.5.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.cons.slice.arr"> [lib.cons.slice.arr]</a> |
| </li> |
| <li> change paragraph 1 of 26.5.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.cons.slice.arr"> [lib.cons.slice.arr]</a> to read "This constructor is declared |
| to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.slice.arr.assign"> [lib.slice.arr.assign]</a> |
| </li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.slice.arr.assign"> [lib.slice.arr.assign]</a> to "These assignment operators have"</li> |
| </ul> |
| |
| <p>gslice_array:</p> |
| <ul> |
| <li> Make the copy constructor and copy-assignment operator declarations |
| public in the gslice_array class template definition in 26.5.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.gslice.array"> [lib.template.gslice.array]</a> </li> |
| <li> remove the note in paragraph 3 of 26.5.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.gslice.array"> [lib.template.gslice.array]</a> |
| </li> |
| <li> remove the copy constructor declaration from 26.5.7.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.gslice.array.cons"> [lib.gslice.array.cons]</a> |
| </li> |
| <li> change paragraph 1 of 26.5.7.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.gslice.array.cons"> [lib.gslice.array.cons]</a> to read "This constructor is declared |
| to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.7.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.gslice.array.assign"> [lib.gslice.array.assign]</a> |
| </li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.7.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.gslice.array.assign"> [lib.gslice.array.assign]</a> to "These assignment operators have"</li> |
| </ul> |
| |
| <p>mask_array:</p> |
| <ul> |
| <li> Make the copy constructor and copy-assignment operator declarations |
| public in the mask_array class template definition in 26.5.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.mask.array"> [lib.template.mask.array]</a> </li> |
| <li> remove the note in paragraph 2 of 26.5.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.mask.array"> [lib.template.mask.array]</a> |
| </li> |
| <li> remove the copy constructor declaration from 26.5.8.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.mask.array.cons"> [lib.mask.array.cons]</a> |
| </li> |
| <li> change paragraph 1 of 26.5.8.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.mask.array.cons"> [lib.mask.array.cons]</a> to read "This constructor is declared |
| to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.8.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.mask.array.assign"> [lib.mask.array.assign]</a> |
| </li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.8.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.mask.array.assign"> [lib.mask.array.assign]</a> to "These assignment operators have"</li> |
| </ul> |
| |
| <p>indirect_array:</p> |
| <ul> |
| <li>Make the copy constructor and copy-assignment operator declarations |
| public in the indirect_array class definition in 26.5.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.indirect.array"> [lib.template.indirect.array]</a> |
| </li> |
| <li> remove the note in paragraph 2 of 26.5.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.template.indirect.array"> [lib.template.indirect.array]</a> |
| </li> |
| <li> remove the copy constructor declaration from 26.5.9.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.indirect.array.cons"> [lib.indirect.array.cons]</a> |
| </li> |
| <li> change the descriptive text in 26.5.9.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.indirect.array.cons"> [lib.indirect.array.cons]</a> to read "This constructor is |
| declared to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.9.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.indirect.array.assign"> [lib.indirect.array.assign]</a> |
| </li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.9.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.indirect.array.assign"> [lib.indirect.array.assign]</a> to "These assignment operators have"</li> |
| </ul> |
| <p><i>[Proposed resolution was modified in Santa Cruz: explicitly make |
| copy constructor and copy assignment operators public, instead of |
| removing them.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p>Keeping the valarray constructors private is untenable. Merely |
| making valarray a friend of the helper classes isn't good enough, |
| because access to the copy constructor is checked in the user's |
| environment.</p> |
| |
| <p>Making the assignment operator public is not strictly necessary to |
| solve this problem. A majority of the LWG <i>(straw poll: 13-4)</i> |
| believed we should make the assignment operators public, in addition |
| to the copy constructors, for reasons of symmetry and user |
| expectation.</p> |
| <hr> |
| <a name="256"><h3>256. typo in 27.4.4.2, p17: copy_event does not exist</h3></a><p><b>Section:</b> 27.4.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.members"> [lib.basic.ios.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 21 Aug 2000</p> |
| <p> |
| 27.4.4.2, p17 says |
| </p> |
| |
| <blockquote> |
| -17- Before copying any parts of rhs, calls each registered callback |
| pair (fn,index) as (*fn)(erase_event,*this,index). After all parts but |
| exceptions() have been replaced, calls each callback pair that was |
| copied from rhs as (*fn)(copy_event,*this,index). |
| </blockquote> |
| |
| <p> |
| The name copy_event isn't defined anywhere. The intended name was |
| copyfmt_event. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace copy_event with copyfmt_event in the named paragraph.</p> |
| <hr> |
| <a name="259"><h3>259. <tt>basic_string::operator[]</tt> and const correctness</h3></a><p><b>Section:</b> 21.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string.access"> [lib.string.access]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Chris Newton <b>Date:</b> 27 Aug 2000</p> |
| <p> |
| <i>Paraphrased from a message that Chris Newton posted to comp.std.c++:</i> |
| </p> |
| |
| <p> |
| The standard's description of <tt>basic_string<>::operator[]</tt> |
| seems to violate const correctness. |
| </p> |
| |
| <p> |
| The standard (21.3.4/1) says that "If <tt>pos < size()</tt>, |
| returns <tt>data()[pos]</tt>." The types don't work. The |
| return value of <tt>data()</tt> is <tt>const charT*</tt>, but |
| <tt>operator[]</tt> has a non-const version whose return type is <tt>reference</tt>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In section 21.3.4, paragraph 1, change |
| "<tt>data()[<i>pos</i>]</tt>" to "<tt>*(begin() + |
| <i>pos</i>)</tt>". |
| </p> |
| <hr> |
| <a name="260"><h3>260. Inconsistent return type of <tt>istream_iterator::operator++(int)</tt> |
| </h3></a><p><b>Section:</b> 24.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istream.iterator.ops"> [lib.istream.iterator.ops]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 27 Aug 2000</p> |
| <p>The synopsis of istream_iterator::operator++(int) in 24.5.1 shows |
| it as returning the iterator by value. 24.5.1.2, p5 shows the same |
| operator as returning the iterator by reference. That's incorrect |
| given the Effects clause below (since a temporary is returned). The |
| `&' is probably just a typo.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the declaration in 24.5.1.2, p5 from</p> |
| <pre> istream_iterator<T,charT,traits,Distance>& operator++(int); |
| </pre> |
| <p>to</p> |
| <pre> istream_iterator<T,charT,traits,Distance> operator++(int); |
| </pre> |
| <p>(that is, remove the `&').</p> |
| <hr> |
| <a name="261"><h3>261. Missing description of <tt>istream_iterator::operator!=</tt> |
| </h3></a><p><b>Section:</b> 24.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istream.iterator.ops"> [lib.istream.iterator.ops]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 27 Aug 2000</p> |
| <p> |
| 24.5.1, p3 lists the synopsis for |
| </p> |
| |
| <pre> template <class T, class charT, class traits, class Distance> |
| bool operator!=(const istream_iterator<T,charT,traits,Distance>& x, |
| const istream_iterator<T,charT,traits,Distance>& y); |
| </pre> |
| |
| <p> |
| but there is no description of what the operator does (i.e., no Effects |
| or Returns clause) in 24.5.1.2. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add paragraph 7 to the end of section 24.5.1.2 with the following text: |
| </p> |
| |
| <pre> template <class T, class charT, class traits, class Distance> |
| bool operator!=(const istream_iterator<T,charT,traits,Distance>& x, |
| const istream_iterator<T,charT,traits,Distance>& y); |
| </pre> |
| |
| <p>-7- Returns: !(x == y).</p> |
| <hr> |
| <a name="262"><h3>262. Bitmask operator ~ specified incorrectly</h3></a><p><b>Section:</b> 17.3.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 03 Sep 2000</p> |
| <p> |
| The ~ operation should be applied after the cast to int_type. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 17.3.2.1.2 [lib.bitmask.types] operator~ from: |
| </p> |
| |
| <pre> bitmask operator~ ( bitmask X ) |
| { return static_cast< bitmask>(static_cast<int_type>(~ X)); } |
| </pre> |
| |
| <p> |
| to: |
| </p> |
| |
| <pre> bitmask operator~ ( bitmask X ) |
| { return static_cast< bitmask>(~static_cast<int_type>(X)); } |
| </pre> |
| <hr> |
| <a name="263"><h3>263. Severe restriction on <tt>basic_string</tt> reference counting</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#WP">WP</a> <b>Submitter:</b> Kevlin Henney <b>Date:</b> 04 Sep 2000</p> |
| <p> |
| The note in paragraph 6 suggests that the invalidation rules for |
| references, pointers, and iterators in paragraph 5 permit a reference- |
| counted implementation (actually, according to paragraph 6, they permit |
| a "reference counted implementation", but this is a minor editorial fix). |
| </p> |
| |
| <p> |
| However, the last sub-bullet is so worded as to make a reference-counted |
| implementation unviable. In the following example none of the |
| conditions for iterator invalidation are satisfied: |
| </p> |
| |
| <pre> // first example: "*******************" should be printed twice |
| string original = "some arbitrary text", copy = original; |
| const string & alias = original; |
| |
| string::const_iterator i = alias.begin(), e = alias.end(); |
| for(string::iterator j = original.begin(); j != original.end(); ++j) |
| *j = '*'; |
| while(i != e) |
| cout << *i++; |
| cout << endl; |
| cout << original << endl; |
| </pre> |
| |
| <p> |
| Similarly, in the following example: |
| </p> |
| |
| <pre> // second example: "some arbitrary text" should be printed out |
| string original = "some arbitrary text", copy = original; |
| const string & alias = original; |
| |
| string::const_iterator i = alias.begin(); |
| original.begin(); |
| while(i != alias.end()) |
| cout << *i++; |
| </pre> |
| |
| <p> |
| I have tested this on three string implementations, two of which were |
| reference counted. The reference-counted implementations gave |
| "surprising behavior" because they invalidated iterators on |
| the first call to non-const begin since construction. The current |
| wording does not permit such invalidation because it does not take |
| into account the first call since construction, only the first call |
| since various member and non-member function calls. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the following sentence in 21.3 paragraph 5 from |
| </p> |
| |
| <blockquote> |
| Subsequent to any of the above uses except the forms of insert() and |
| erase() which return iterators, the first call to non-const member |
| functions operator[](), at(), begin(), rbegin(), end(), or rend(). |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| Following construction or any of the above uses, except the forms of |
| insert() and erase() that return iterators, the first call to non- |
| const member functions operator[](), at(), begin(), rbegin(), end(), |
| or rend(). |
| </blockquote> |
| <hr> |
| <a name="264"><h3>264. Associative container <tt>insert(i, j)</tt> complexity requirements are not feasible.</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#WP">WP</a> <b>Submitter:</b> John Potter <b>Date:</b> 07 Sep 2000</p> |
| <p> |
| Table 69 requires linear time if [i, j) is sorted. Sorted is necessary but not sufficient. |
| Consider inserting a sorted range of even integers into a set<int> containing the odd |
| integers in the same range. |
| </p> |
| |
| <p><i>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#102">102</a></i></p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In Table 69, in section 23.1.2, change the complexity clause for |
| insertion of a range from "N log(size() + N) (N is the distance |
| from i to j) in general; linear if [i, j) is sorted according to |
| value_comp()" to "N log(size() + N), where N is the distance |
| from i to j". |
| </p> |
| |
| <p><i>[Copenhagen: Minor fix in proposed resolution: fixed unbalanced |
| parens in the revised wording.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Testing for valid insertions could be less efficient than simply |
| inserting the elements when the range is not both sorted and between |
| two adjacent existing elements; this could be a QOI issue. |
| </p> |
| |
| <p> |
| The LWG considered two other options: (a) specifying that the |
| complexity was linear if [i, j) is sorted according to value_comp() |
| and between two adjacent existing elements; or (b) changing to |
| Klog(size() + N) + (N - K) (N is the distance from i to j and K is the |
| number of elements which do not insert immediately after the previous |
| element from [i, j) including the first). The LWG felt that, since |
| we can't guarantee linear time complexity whenever the range to be |
| inserted is sorted, it's more trouble than it's worth to say that it's |
| linear in some special cases. |
| </p> |
| <hr> |
| <a name="265"><h3>265. std::pair::pair() effects overly restrictive</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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 11 Sep 2000</p> |
| <p> |
| I don't see any requirements on the types of the elements of the |
| std::pair container in 20.2.2. From the descriptions of the member |
| functions it appears that they must at least satisfy the requirements of |
| 20.1.3 [lib.copyconstructible] and 20.1.4 [lib.default.con.req], and in |
| the case of the [in]equality operators also the requirements of 20.1.1 |
| [lib.equalitycomparable] and 20.1.2 [lib.lessthancomparable]. |
| </p> |
| |
| <p> |
| I believe that the the CopyConstructible requirement is unnecessary in |
| the case of 20.2.2, p2. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the Effects clause in 20.2.2, p2 from</p> |
| |
| <blockquote> |
| -2- <b>Effects</b>: Initializes its members as if implemented: <tt> pair() : |
| first(T1()), second(T2()) {} </tt> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| -2- <b>Effects</b>: Initializes its members as if implemented: <tt> pair() : |
| first(), second() {} </tt> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>The existing specification of pair's constructor appears to be a |
| historical artifact: there was concern that pair's members be properly |
| zero-initialized when they are built-in types. At one time there was |
| uncertainty about whether they would be zero-initialized if the |
| default constructor was written the obvious way. This has been |
| clarified by core issue 178, and there is no longer any doubt that |
| the straightforward implementation is correct.</p> |
| <hr> |
| <a name="266"><h3>266. bad_exception::~bad_exception() missing Effects clause</h3></a><p><b>Section:</b> 18.7.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.bad.exception"> [lib.bad.exception]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 24 Sep 2000</p> |
| <p> |
| The synopsis for std::bad_exception lists the function ~bad_exception() |
| but there is no description of what the function does (the Effects |
| clause is missing). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove the destructor from the class synopses of |
| <tt>bad_alloc</tt> (<font color="red">18.4.2.1</font>), |
| <tt>bad_cast</tt> (18.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.alloc.errors"> [lib.alloc.errors]</a>), |
| <tt>bad_typeid</tt> (<font color="red">18.5.3</font>), |
| and <tt>bad_exception</tt> (18.7.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.bad.exception"> [lib.bad.exception]</a>). |
| </p> |
| <p><b>Rationale:</b></p> |
| <p> |
| This is a general problem with the exception classes in clause 18. |
| The proposed resolution is to remove the destructors from the class |
| synopses, rather than to document the destructors' behavior, because |
| removing them is more consistent with how exception classes are |
| described in clause 19. |
| </p> |
| <hr> |
| <a name="268"><h3>268. Typo in locale synopsis</h3></a><p><b>Section:</b> 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 5 Oct 2000</p> |
| <p>The synopsis of the class std::locale in 22.1.1 contains two typos: |
| the semicolons after the declarations of the default ctor |
| locale::locale() and the copy ctor locale::locale(const locale&) |
| are missing.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the missing semicolons, i.e., change</p> |
| |
| <pre> // construct/copy/destroy: |
| locale() throw() |
| locale(const locale& other) throw() |
| </pre> |
| |
| <p>in the synopsis in 22.1.1 to</p> |
| |
| <pre> // construct/copy/destroy: |
| locale() throw(); |
| locale(const locale& other) throw(); |
| </pre> |
| <hr> |
| <a name="270"><h3>270. Binary search requirements overly strict</h3></a><p><b>Section:</b> 25.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.binary.search"> [lib.alg.binary.search]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 18 Oct 2000</p> |
| <p> |
| Each of the four binary search algorithms (lower_bound, upper_bound, |
| equal_range, binary_search) has a form that allows the user to pass a |
| comparison function object. According to 25.3, paragraph 2, that |
| comparison function object has to be a strict weak ordering. |
| </p> |
| |
| <p> |
| This requirement is slightly too strict. Suppose we are searching |
| through a sequence containing objects of type X, where X is some |
| large record with an integer key. We might reasonably want to look |
| up a record by key, in which case we would want to write something |
| like this: |
| </p> |
| <pre> struct key_comp { |
| bool operator()(const X& x, int n) const { |
| return x.key() < n; |
| } |
| } |
| |
| std::lower_bound(first, last, 47, key_comp()); |
| </pre> |
| |
| <p> |
| key_comp is not a strict weak ordering, but there is no reason to |
| prohibit its use in lower_bound. |
| </p> |
| |
| <p> |
| There's no difficulty in implementing lower_bound so that it allows |
| the use of something like key_comp. (It will probably work unless an |
| implementor takes special pains to forbid it.) What's difficult is |
| formulating language in the standard to specify what kind of |
| comparison function is acceptable. We need a notion that's slightly |
| more general than that of a strict weak ordering, one that can encompass |
| a comparison function that involves different types. Expressing that |
| notion may be complicated. |
| </p> |
| |
| <p><i>Additional questions raised at the Toronto meeting:</i></p> |
| <ul> |
| <li> Do we really want to specify what ordering the implementor must |
| use when calling the function object? The standard gives |
| specific expressions when describing these algorithms, but it also |
| says that other expressions (with different argument order) are |
| equivalent.</li> |
| <li> If we are specifying ordering, note that the standard uses both |
| orderings when describing <tt>equal_range</tt>.</li> |
| <li> Are we talking about requiring these algorithms to work properly |
| when passed a binary function object whose two argument types |
| are not the same, or are we talking about requirements when |
| they are passed a binary function object with several overloaded |
| versions of <tt>operator()</tt>?</li> |
| <li> The definition of a strict weak ordering does not appear to give |
| any guidance on issues of overloading; it only discusses expressions, |
| and all of the values in these expressions are of the same type. |
| Some clarification would seem to be in order.</li> |
| </ul> |
| |
| <p><i>Additional discussion from Copenhagen:</i></p> |
| <ul> |
| <li>It was generally agreed that there is a real defect here: if |
| the predicate is merely required to be a Strict Weak Ordering, then |
| it's possible to pass in a function object with an overloaded |
| operator(), where the version that's actually called does something |
| completely inappropriate. (Such as returning a random value.)</li> |
| |
| <li>An alternative formulation was presented in a paper distributed by |
| David Abrahams at the meeting, "Binary Search with Heterogeneous |
| Comparison", J16-01/0027 = WG21 N1313: Instead of viewing the |
| predicate as a Strict Weak Ordering acting on a sorted sequence, view |
| the predicate/value pair as something that partitions a sequence. |
| This is almost equivalent to saying that we should view binary search |
| as if we are given a unary predicate and a sequence, such that f(*p) |
| is true for all p below a specific point and false for all p above it. |
| The proposed resolution is based on that alternative formulation.</li> |
| </ul> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change 25.3 [lib.alg.sorting] paragraph 3 from:</p> |
| |
| <blockquote> |
| 3 For all algorithms that take Compare, there is a version that uses |
| operator< instead. That is, comp(*i, *j) != false defaults to *i < |
| *j != false. For the algorithms to work correctly, comp has to |
| induce a strict weak ordering on the values. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| 3 For all algorithms that take Compare, there is a version that uses |
| operator< instead. That is, comp(*i, *j) != false defaults to *i |
| < *j != false. For algorithms other than those described in |
| lib.alg.binary.search (25.3.3) to work correctly, comp has to induce |
| a strict weak ordering on the values. |
| </blockquote> |
| |
| <p>Add the following paragraph after 25.3 [lib.alg.sorting] paragraph 5:</p> |
| |
| <blockquote> |
| -6- A sequence [start, finish) is partitioned with respect to an |
| expression f(e) if there exists an integer n such that |
| for all 0 <= i < distance(start, finish), f(*(begin+i)) is true if |
| and only if i < n. |
| </blockquote> |
| |
| <p>Change 25.3.3 [lib.alg.binary.search] paragraph 1 from:</p> |
| |
| <blockquote> |
| -1- All of the algorithms in this section are versions of binary |
| search and assume that the sequence being searched is in order |
| according to the implied or explicit comparison function. They work |
| on non-random access iterators minimizing the number of |
| comparisons, which will be logarithmic for all types of |
| iterators. They are especially appropriate for random access |
| iterators, because these algorithms do a logarithmic number of |
| steps through the data structure. For non-random access iterators |
| they execute a linear number of steps. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -1- All of the algorithms in this section are versions of binary |
| search and assume that the sequence being searched is partitioned |
| with respect to an expression formed by binding the search key to |
| an argument of the implied or explicit comparison function. They |
| work on non-random access iterators minimizing the number of |
| comparisons, which will be logarithmic for all types of |
| iterators. They are especially appropriate for random access |
| iterators, because these algorithms do a logarithmic number of |
| steps through the data structure. For non-random access iterators |
| they execute a linear number of steps. |
| </blockquote> |
| |
| <p>Change 25.3.3.1 [lib.lower.bound] paragraph 1 from:</p> |
| |
| <blockquote> |
| -1- Requires: Type T is LessThanComparable |
| (lib.lessthancomparable). |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expression e < value or comp(e, value) |
| </blockquote> |
| |
| |
| <p>Remove 25.3.3.1 [lib.lower.bound] paragraph 2:</p> |
| |
| <blockquote> |
| -2- Effects: Finds the first position into which value can be |
| inserted without violating the ordering. |
| </blockquote> |
| |
| <p>Change 25.3.3.2 [lib.upper.bound] paragraph 1 from:</p> |
| |
| <blockquote> |
| -1- Requires: Type T is LessThanComparable (lib.lessthancomparable). |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expression !(value < e) or !comp(value, e) |
| </blockquote> |
| |
| <p>Remove 25.3.3.2 [lib.upper.bound] paragraph 2:</p> |
| |
| <blockquote> |
| -2- Effects: Finds the furthermost position into which value can be |
| inserted without violating the ordering. |
| </blockquote> |
| |
| <p>Change 25.3.3.3 [lib.equal.range] paragraph 1 from:</p> |
| |
| <blockquote> |
| -1- Requires: Type T is LessThanComparable |
| (lib.lessthancomparable). |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expressions e < value and !(value < e) or |
| comp(e, value) and !comp(value, e). Also, for all elements e of |
| [first, last), e < value implies !(value < e) or comp(e, |
| value) implies !comp(value, e) |
| </blockquote> |
| |
| <p>Change 25.3.3.3 [lib.equal.range] paragraph 2 from:</p> |
| |
| <blockquote> |
| -2- Effects: Finds the largest subrange [i, j) such that the value |
| can be inserted at any iterator k in it without violating the |
| ordering. k satisfies the corresponding conditions: !(*k < value) |
| && !(value < *k) or comp(*k, value) == false && comp(value, *k) == |
| false. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <pre> -2- Returns: |
| make_pair(lower_bound(first, last, value), |
| upper_bound(first, last, value)) |
| or |
| make_pair(lower_bound(first, last, value, comp), |
| upper_bound(first, last, value, comp)) |
| </pre> |
| |
| <p>Change 25.3.3.3 [lib.binary.search] paragraph 1 from:</p> |
| |
| <blockquote> |
| -1- Requires: Type T is LessThanComparable |
| (lib.lessthancomparable). |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expressions e < value and !(value < e) or comp(e, |
| value) and !comp(value, e). Also, for all elements e of [first, |
| last), e < value implies !(value < e) or comp(e, value) implies |
| !comp(value, e) |
| </blockquote> |
| |
| <p><i>[Copenhagen: Dave Abrahams provided this wording]</i></p> |
| |
| <p><i>[Redmond: Minor changes in wording. (Removed "non-negative", and |
| changed the "other than those described in" wording.) Also, the LWG |
| decided to accept the "optional" part.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The proposed resolution reinterprets binary search. Instead of |
| thinking about searching for a value in a sorted range, we view that |
| as an important special case of a more general algorithm: searching |
| for the partition point in a partitioned range.</p> |
| |
| <p>We also add a guarantee that the old wording did not: we ensure |
| that the upper bound is no earlier than the lower bound, that |
| the pair returned by equal_range is a valid range, and that the first |
| part of that pair is the lower bound.</p> |
| <hr> |
| <a name="271"><h3>271. basic_iostream missing typedefs</h3></a><p><b>Section:</b> 27.6.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostreamclass"> [lib.iostreamclass]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 02 Nov 2000</p> |
| <p> |
| Class template basic_iostream has no typedefs. The typedefs it |
| inherits from its base classes can't be used, since (for example) |
| basic_iostream<T>::traits_type is ambiguous. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following to basic_iostream's class synopsis in |
| 27.6.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostreamclass"> [lib.iostreamclass]</a>, immediately after <tt>public</tt>:</p> |
| |
| <pre> // types: |
| typedef charT char_type; |
| typedef typename traits::int_type int_type; |
| typedef typename traits::pos_type pos_type; |
| typedef typename traits::off_type off_type; |
| typedef traits traits_type; |
| </pre> |
| <hr> |
| <a name="272"><h3>272. Missing parentheses around subexpression</h3></a><p><b>Section:</b> 27.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostate.flags"> [lib.iostate.flags]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 02 Nov 2000</p> |
| <p> |
| 27.4.4.3, p4 says about the postcondition of the function: If |
| rdbuf()!=0 then state == rdstate(); otherwise |
| rdstate()==state|ios_base::badbit. |
| </p> |
| |
| <p> |
| The expression on the right-hand-side of the operator==() needs to be |
| parenthesized in order for the whole expression to ever evaluate to |
| anything but non-zero. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add parentheses like so: rdstate()==(state|ios_base::badbit). |
| </p> |
| <hr> |
| <a name="273"><h3>273. Missing ios_base qualification on members of a dependent class</h3></a><p><b>Section:</b> 27 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 02 Nov 2000</p> |
| <p>27.5.2.4.2, p4, and 27.8.1.6, p2, 27.8.1.7, p3, 27.8.1.9, p2, |
| 27.8.1.10, p3 refer to in and/or out w/o ios_base:: qualification. |
| That's incorrect since the names are members of a dependent base |
| class (14.6.2 [temp.dep]) and thus not visible.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Qualify the names with the name of the class of which they are |
| members, i.e., ios_base.</p> |
| <hr> |
| <a name="274"><h3>274. a missing/impossible 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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 02 Nov 2000</p> |
| <p> |
| I see that table 31 in 20.1.5, p3 allows T in std::allocator<T> to be of |
| any type. But the synopsis in 20.4.1 calls for allocator<>::address() to |
| be overloaded on reference and const_reference, which is ill-formed for |
| all T = const U. In other words, this won't work: |
| </p> |
| |
| <p> |
| template class std::allocator<const int>; |
| </p> |
| |
| <p> |
| The obvious solution is to disallow specializations of allocators on |
| const types. However, while containers' elements are required to be |
| assignable (which rules out specializations on const T's), I think that |
| allocators might perhaps be potentially useful for const values in other |
| contexts. So if allocators are to allow const types a partial |
| specialization of std::allocator<const T> would probably have to be |
| provided. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the text in row 1, column 2 of table 32 in 20.1.5, p3 from</p> |
| |
| <blockquote> |
| any type |
| </blockquote> |
| |
| <p>to</p> |
| <blockquote> |
| any non-const, non-reference type |
| </blockquote> |
| |
| <p><i>[Redmond: previous proposed resolution was "any non-const, |
| non-volatile, non-reference type". Got rid of the "non-volatile".]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Two resolutions were originally proposed: one that partially |
| specialized std::allocator for const types, and one that said an |
| allocator's value type may not be const. The LWG chose the second. |
| The first wouldn't be appropriate, because allocators are intended for |
| use by containers, and const value types don't work in containers. |
| Encouraging the use of allocators with const value types would only |
| lead to unsafe code. |
| </p> |
| <p> |
| The original text for proposed resolution 2 was modified so that it |
| also forbids volatile types and reference types. |
| </p> |
| |
| <p><i>[Curaçao: LWG double checked and believes volatile is correctly |
| excluded from the PR.]</i></p> |
| |
| <hr> |
| <a name="275"><h3>275. Wrong type in num_get::get() overloads</h3></a><p><b>Section:</b> 22.2.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.members"> [lib.facet.num.get.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 02 Nov 2000</p> |
| <p> |
| In 22.2.2.1.1, we have a list of overloads for num_get<>::get(). |
| There are eight overloads, all of which are identical except for the |
| last parameter. The overloads are: |
| </p> |
| <ul> |
| <li> long& </li> |
| <li> unsigned short& </li> |
| <li> unsigned int& </li> |
| <li> unsigned long& </li> |
| <li> short& </li> |
| <li> double& </li> |
| <li> long double& </li> |
| <li> void*& </li> |
| </ul> |
| |
| <p> |
| There is a similar list, in 22.2.2.1.2, of overloads for |
| num_get<>::do_get(). In this list, the last parameter has |
| the types: |
| </p> |
| <ul> |
| <li> long& </li> |
| <li> unsigned short& </li> |
| <li> unsigned int& </li> |
| <li> unsigned long& </li> |
| <li> float& </li> |
| <li> double& </li> |
| <li> long double& </li> |
| <li> void*& </li> |
| </ul> |
| |
| <p> |
| These two lists are not identical. They should be, since |
| <tt>get</tt> is supposed to call <tt>do_get</tt> with exactly |
| the arguments it was given. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.get.members"> [lib.facet.num.get.members]</a>, change</p> |
| <pre> iter_type get(iter_type in, iter_type end, ios_base& str, |
| ios_base::iostate& err, short& val) const; |
| </pre> |
| <p>to</p> |
| <pre> iter_type get(iter_type in, iter_type end, ios_base& str, |
| ios_base::iostate& err, float& val) const; |
| </pre> |
| <hr> |
| <a name="276"></a><h3><a name="276">276. Assignable requirement for container value type overly strict</a></h3><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#WP">WP</a> <b>Submitter:</b> Peter Dimov <b>Date:</b> 07 Nov 2000</p> |
| <p> |
| 23.1/3 states that the objects stored in a container must be |
| Assignable. 23.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map"> [lib.map]</a>, paragraph 2, |
| states that map satisfies all requirements for a container, while in |
| the same time defining value_type as pair<const Key, T> - a type |
| that is not Assignable. |
| </p> |
| |
| <p> |
| It should be noted that there exists a valid and non-contradictory |
| interpretation of the current text. The wording in 23.1/3 avoids |
| mentioning value_type, referring instead to "objects stored in a |
| container." One might argue that map does not store objects of |
| type map::value_type, but of map::mapped_type instead, and that the |
| Assignable requirement applies to map::mapped_type, not |
| map::value_type. |
| </p> |
| |
| <p> |
| However, this makes map a special case (other containers store objects of |
| type value_type) and the Assignable requirement is needlessly restrictive in |
| general. |
| </p> |
| |
| <p> |
| For example, the proposed resolution of active library issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103">103</a> is to make set::iterator a constant iterator; this |
| means that no set operations can exploit the fact that the stored |
| objects are Assignable. |
| </p> |
| |
| <p> |
| This is related to, but slightly broader than, closed issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#140">140</a>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>23.1/3: Strike the trailing part of the sentence:</p> |
| <blockquote> |
| , and the additional requirements of Assignable types from 23.1/3 |
| </blockquote> |
| <p>so that it reads:</p> |
| <blockquote> |
| -3- The type of objects stored in these components must meet the |
| requirements of CopyConstructible types (lib.copyconstructible). |
| </blockquote> |
| |
| <p>23.1/4: Modify to make clear that this requirement is not for all |
| containers. Change to:</p> |
| |
| <blockquote> |
| -4- Table 64 defines the Assignable requirement. Some containers |
| require this property of the types to be stored in the container. T is |
| the type used to instantiate the container. t is a value of T, and u is |
| a value of (possibly const) T. |
| </blockquote> |
| |
| <p>23.1, Table 65: in the first row, change "T is Assignable" to "T is |
| CopyConstructible".</p> |
| |
| <p>23.2.1/2: Add sentence for Assignable requirement. Change to:</p> |
| |
| <blockquote> |
| -2- A deque satisfies all of the requirements of a container and of a |
| reversible container (given in tables in lib.container.requirements) and |
| of a sequence, including the optional sequence requirements |
| (lib.sequence.reqmts). In addition to the requirements on the stored |
| object described in 23.1[lib.container.requirements], the stored object |
| must also meet the requirements of Assignable. Descriptions are |
| provided here only for operations on deque that are not described in one |
| of these tables or for operations where there is additional semantic |
| information. |
| </blockquote> |
| |
| <p>23.2.2/2: Add Assignable requirement to specific methods of list. |
| Change to:</p> |
| |
| <blockquote> |
| <p>-2- A list satisfies all of the requirements of a container and of a |
| reversible container (given in two tables in lib.container.requirements) |
| and of a sequence, including most of the the optional sequence |
| requirements (lib.sequence.reqmts). The exceptions are the operator[] |
| and at member functions, which are not provided. |
| |
| [Footnote: These member functions are only provided by containers whose |
| iterators are random access iterators. --- end foonote] |
| </p> |
| |
| <p>list does not require the stored type T to be Assignable unless the |
| following methods are instantiated: |
| |
| [Footnote: Implementors are permitted but not required to take advantage |
| of T's Assignable properties for these methods. -- end foonote] |
| </p> |
| <pre> list<T,Allocator>& operator=(const list<T,Allocator>& x ); |
| template <class InputIterator> |
| void assign(InputIterator first, InputIterator last); |
| void assign(size_type n, const T& t); |
| </pre> |
| |
| |
| <p>Descriptions are provided here only for operations on list that are not |
| described in one of these tables or for operations where there is |
| additional semantic information.</p> |
| </blockquote> |
| |
| <p>23.2.4/2: Add sentence for Assignable requirement. Change to:</p> |
| |
| <blockquote> |
| -2- A vector satisfies all of the requirements of a container and of a |
| reversible container (given in two tables in lib.container.requirements) |
| and of a sequence, including most of the optional sequence requirements |
| (lib.sequence.reqmts). The exceptions are the push_front and pop_front |
| member functions, which are not provided. In addition to the |
| requirements on the stored object described in |
| 23.1[lib.container.requirements], the stored object must also meet the |
| requirements of Assignable. Descriptions are provided here only for |
| operations on vector that are not described in one of these tables or |
| for operations where there is additional semantic information. |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>list, set, multiset, map, multimap are able to store non-Assignables. |
| However, there is some concern about <tt>list<T></tt>: |
| although in general there's no reason for T to be Assignable, some |
| implementations of the member functions <tt>operator=</tt> and |
| <tt>assign</tt> do rely on that requirement. The LWG does not want |
| to forbid such implementations.</p> |
| |
| <p>Note that the type stored in a standard container must still satisfy |
| the requirements of the container's allocator; this rules out, for |
| example, such types as "const int". See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#274">274</a> |
| for more details. |
| </p> |
| |
| <p>In principle we could also relax the "Assignable" requirement for |
| individual <tt>vector</tt> member functions, such as |
| <tt>push_back</tt>. However, the LWG did not see great value in such |
| selective relaxation. Doing so would remove implementors' freedom to |
| implement <tt>vector::push_back</tt> in terms of |
| <tt>vector::insert</tt>.</p> |
| |
| <hr> |
| <a name="278"><h3>278. What does iterator validity mean?</h3></a><p><b>Section:</b> 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> P.J. Plauger <b>Date:</b> 27 Nov 2000</p> |
| <p> |
| Section 23.2.2.4 [lib.list.ops] states that |
| </p> |
| <pre> void splice(iterator position, list<T, Allocator>& x); |
| </pre> |
| <p> |
| <i>invalidates</i> all iterators and references to list <tt>x</tt>. |
| </p> |
| |
| <p> |
| But what does the C++ Standard mean by "invalidate"? You |
| can still dereference the iterator to a spliced list element, but |
| you'd better not use it to delimit a range within the original |
| list. For the latter operation, it has definitely lost some of its |
| validity. |
| </p> |
| |
| <p> |
| If we accept the proposed resolution to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#250">250</a>, |
| then we'd better clarify that a "valid" iterator need no |
| longer designate an element within the same container as it once did. |
| We then have to clarify what we mean by invalidating a past-the-end |
| iterator, as when a vector or string grows by reallocation. Clearly, |
| such an iterator has a different kind of validity. Perhaps we should |
| introduce separate terms for the two kinds of "validity." |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text to the end of section 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>, |
| after paragraph 5:</p> |
| <blockquote> |
| An <i>invalid</i> iterator is an iterator that may be |
| singular. [Footnote: This definition applies to pointers, since |
| pointers are iterators. The effect of dereferencing an iterator that |
| has been invalidated is undefined.] |
| </blockquote> |
| |
| <p><i>[post-Copenhagen: Matt provided wording.]</i></p> |
| |
| <p><i>[Redmond: General agreement with the intent, some objections to |
| the wording. Dave provided new wording.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p>This resolution simply defines a term that the Standard uses but |
| never defines, "invalid", in terms of a term that is defined, |
| "singular".</p> |
| |
| <p>Why do we say "may be singular", instead of "is singular"? That's |
| becuase a valid iterator is one that is known to be nonsingular. |
| Invalidating an iterator means changing it in such a way that it's |
| no longer known to be nonsingular. An example: inserting an |
| element into the middle of a vector is correctly said to invalidate |
| all iterators pointing into the vector. That doesn't necessarily |
| mean they all become singular.</p> |
| <hr> |
| <a name="280"><h3>280. Comparison of reverse_iterator to const reverse_iterator</h3></a><p><b>Section:</b> 24.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iterators"> [lib.reverse.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Steve Cleary <b>Date:</b> 27 Nov 2000</p> |
| <p> |
| This came from an email from Steve Cleary to Fergus in reference to |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a>. The library working group briefly discussed |
| this in Toronto and believed it should be a separate issue. There was |
| also some reservations about whether this was a worthwhile problem to |
| fix. |
| </p> |
| |
| <p> |
| Steve said: "Fixing reverse_iterator. std::reverse_iterator can |
| (and should) be changed to preserve these additional |
| requirements." He also said in email that it can be done without |
| breaking user's code: "If you take a look at my suggested |
| solution, reverse_iterator doesn't have to take two parameters; there |
| is no danger of breaking existing code, except someone taking the |
| address of one of the reverse_iterator global operator functions, and |
| I have to doubt if anyone has ever done that. . . <i>But</i>, just in |
| case they have, you can leave the old global functions in as well -- |
| they won't interfere with the two-template-argument functions. With |
| that, I don't see how <i>any</i> user code could break." |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| <b>Section:</b> 24.4.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iterator"> [lib.reverse.iterator]</a> |
| add/change the following declarations:</p> |
| <pre> A) Add a templated assignment operator, after the same manner |
| as the templated copy constructor, i.e.: |
| |
| template < class U > |
| reverse_iterator < Iterator >& operator=(const reverse_iterator< U >& u); |
| |
| B) Make all global functions (except the operator+) have |
| two template parameters instead of one, that is, for |
| operator ==, !=, <, >, <=, >=, - replace: |
| |
| template < class Iterator > |
| typename reverse_iterator< Iterator >::difference_type operator-( |
| const reverse_iterator< Iterator >& x, |
| const reverse_iterator< Iterator >& y); |
| |
| with: |
| |
| template < class Iterator1, class Iterator2 > |
| typename reverse_iterator < Iterator1 >::difference_type operator-( |
| const reverse_iterator < Iterator1 > & x, |
| const reverse_iterator < Iterator2 > & y); |
| </pre> |
| <p> |
| Also make the addition/changes for these signatures in |
| 24.4.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.ops"> [lib.reverse.iter.ops]</a>. |
| </p> |
| |
| <p><i>[ |
| Copenhagen: The LWG is concerned that the proposed resolution |
| introduces new overloads. Experience shows that introducing |
| overloads is always risky, and that it would be inappropriate to |
| make this change without implementation experience. It may be |
| desirable to provide this feature in a different way. |
| ]</i></p> |
| |
| <p><i>[ |
| Lillehammer: We now have implementation experience, and agree that |
| this solution is safe and correct. |
| ]</i></p> |
| |
| <hr> |
| <a name="281"><h3>281. std::min() and max() requirements overly restrictive</h3></a><p><b>Section:</b> 25.3.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.min.max"> [lib.alg.min.max]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 02 Dec 2000</p> |
| <p>The requirements in 25.3.7, p1 and 4 call for T to satisfy the |
| requirements of <tt>LessThanComparable</tt> (20.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.lessthancomparable"> [lib.lessthancomparable]</a>) |
| and <tt>CopyConstructible</tt> (20.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.copyconstructible"> [lib.copyconstructible]</a>). |
| Since the functions take and return their arguments and result by |
| const reference, I believe the <tt>CopyConstructible</tt> requirement |
| is unnecessary. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the <tt>CopyConstructible</tt> requirement. Specifically, replace |
| 25.3.7, p1 with</p> |
| <p><b>-1- Requires:</b> Type T is <tt>LessThanComparable</tt> |
| (20.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.lessthancomparable"> [lib.lessthancomparable]</a>). |
| </p> |
| <p>and replace 25.3.7, p4 with</p> |
| <p><b>-4- Requires:</b> Type T is <tt>LessThanComparable</tt> |
| (20.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.lessthancomparable"> [lib.lessthancomparable]</a>). |
| </p> |
| <hr> |
| <a name="282"><h3>282. What types does numpunct grouping refer to?</h3></a><p><b>Section:</b> 22.2.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 5 Dec 2000</p> |
| <p> |
| Paragraph 16 mistakenly singles out integral types for inserting |
| thousands_sep() characters. This conflicts with the syntax for floating |
| point numbers described under 22.2.3.1/2. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change paragraph 16 from:</p> |
| |
| <blockquote> |
| For integral types, punct.thousands_sep() characters are inserted into |
| the sequence as determined by the value returned by punct.do_grouping() |
| using the method described in 22.2.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.numpunct.virtuals"> [lib.facet.numpunct.virtuals]</a>. |
| </blockquote> |
| |
| <p>To:</p> |
| |
| <blockquote> |
| For arithmetic types, punct.thousands_sep() characters are inserted into |
| the sequence as determined by the value returned by punct.do_grouping() |
| using the method described in 22.2.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.numpunct.virtuals"> [lib.facet.numpunct.virtuals]</a>. |
| </blockquote> |
| |
| <p><i>[ |
| Copenhagen: Opinions were divided about whether this is actually an |
| inconsistency, but at best it seems to have been unintentional. This |
| is only an issue for floating-point output: The standard is |
| unambiguous that implementations must parse thousands_sep characters |
| when performing floating-point. The standard is also unambiguous that |
| this requirement does not apply to the "C" locale. |
| ]</i></p> |
| |
| <p><i>[ |
| A survey of existing practice is needed; it is believed that some |
| implementations do insert thousands_sep characters for floating-point |
| output and others fail to insert thousands_sep characters for |
| floating-point input even though this is unambiguously required by the |
| standard. |
| ]</i></p> |
| |
| <p><i>[Post-Curaçao: the above proposed resolution is the consensus of |
| Howard, Bill, Pete, Benjamin, Nathan, Dietmar, Boris, and Martin.]</i></p> |
| |
| <hr> |
| <a name="283"><h3>283. std::replace() requirement incorrect/insufficient</h3></a><p><b>Section:</b> 25.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 15 Dec 2000</p> |
| <p> |
| (revision of the further discussion) |
| There are a number of problems with the requires clauses for the |
| algorithms in 25.1 and 25.2. The requires clause of each algorithm |
| should describe the necessary and sufficient requirements on the inputs |
| to the algorithm such that the algorithm compiles and runs properly. |
| Many of the requires clauses fail to do this. Here is a summary of the kinds |
| of mistakes: |
| </p> |
| |
| <ol> |
| <li> |
| Use of EqualityComparable, which only puts requirements on a single |
| type, when in fact an equality operator is required between two |
| different types, typically either T and the iterator's value type |
| or between the value types of two different iterators. |
| </li> |
| <li> |
| Use of Assignable for T when in fact what was needed is Assignable |
| for the value_type of the iterator, and convertability from T to the |
| value_type of the iterator. Or for output iterators, the requirement |
| should be that T is writable to the iterator (output iterators do |
| not have value types). |
| </li> |
| </ol> |
| |
| <p> |
| Here is the list of algorithms that contain mistakes: |
| </p> |
| |
| <ul> |
| <li>25.1.2 std::find</li> |
| <li>25.1.6 std::count</li> |
| <li>25.1.8 std::equal</li> |
| <li>25.1.9 std::search, std::search_n</li> |
| <li>25.2.4 std::replace, std::replace_copy</li> |
| <li>25.2.5 std::fill</li> |
| <li>25.2.7 std::remove, std::remove_copy</li> |
| </ul> |
| |
| <p> |
| Also, in the requirements for EqualityComparable, the requirement that |
| the operator be defined for const objects is lacking. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>20.1.1 Change p1 from</p> |
| |
| <p>In Table 28, <tt>T</tt> is a type to be supplied by a C++ program |
| instantiating a template, <tt>a</tt>, <tt>b</tt>, and <tt>c</tt> are |
| values of type <tt>T</tt>. |
| </p> |
| |
| <p>to</p> |
| |
| <p> |
| In Table 28, <tt>T</tt> is a type to be supplied by a C++ program |
| instantiating a template, <tt>a</tt>, <tt>b</tt>, and <tt>c</tt> are |
| values of type <tt>const T</tt>. |
| </p> |
| |
| <p>25 Between p8 and p9</p> |
| |
| <p>Add the following sentence:</p> |
| |
| <p>When the description of an algorithm gives an expression such as |
| <tt>*first == value</tt> for a condition, it is required that the expression |
| evaluate to either true or false in boolean contexts.</p> |
| |
| <p>25.1.2 Change p1 by deleting the requires clause.</p> |
| |
| <p>25.1.6 Change p1 by deleting the requires clause.</p> |
| |
| <p>25.1.9</p> |
| |
| <p>Change p4 from</p> |
| |
| <p>-4- Requires: Type <tt>T</tt> is <tt>EqualityComparable</tt> |
| (20.1.1), type Size is convertible to integral type (4.7.12.3). |
| </p> |
| |
| <p>to</p> |
| |
| <p>-4- Requires: The type <tt>Size</tt> is convertible to integral |
| type (4.7.12.3).</p> |
| |
| <p>25.2.4 Change p1 from</p> |
| |
| <p>-1- Requires: Type <tt>T</tt> is <tt>Assignable</tt> (23.1 ) (and, for <tt>replace()</tt>, <tt>EqualityComparable</tt> (20.1.1 )).</p> |
| |
| <p>to</p> |
| |
| <p>-1- Requires: The expression <tt>*first = new_value</tt> must be valid.</p> |
| |
| <p>and change p4 from</p> |
| |
| <p>-4- Requires: Type <tt>T</tt> is <tt>Assignable</tt> (23.1) (and, |
| for <tt>replace_copy()</tt>, <tt>EqualityComparable</tt> |
| (20.1.1)). The ranges <tt>[first, last)</tt> and <tt>[result, result + |
| (last - first))</tt> shall not overlap.</p> |
| |
| <p>to</p> |
| |
| <p>-4- Requires: The results of the expressions <tt>*first</tt> and |
| <tt>new_value</tt> must be writable to the result output iterator. The |
| ranges <tt>[first, last)</tt> and <tt>[result, result + (last - |
| first))</tt> shall not overlap.</p> |
| |
| |
| <p>25.2.5 Change p1 from</p> |
| |
| <p>-1- Requires: Type <tt>T</tt> is <tt>Assignable</tt> (23.1). The |
| type <tt>Size</tt> is convertible to an integral type (4.7.12.3).</p> |
| |
| <p>to</p> |
| |
| <p>-1- Requires: The expression <tt>value</tt> must be is writable to |
| the output iterator. The type <tt>Size</tt> is convertible to an |
| integral type (4.7.12.3).</p> |
| |
| <p>25.2.7 Change p1 from</p> |
| |
| <p>-1- Requires: Type <tt>T</tt> is <tt>EqualityComparable</tt> (20.1.1).</p> |
| |
| <p>to</p> |
| |
| <p> |
| -1- Requires: The value type of the iterator must be |
| <tt>Assignable</tt> (23.1). |
| </p> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| The general idea of the proposed solution is to remove the faulty |
| requires clauses and let the returns and effects clauses speak for |
| themselves. That is, the returns clauses contain expressions that must |
| be valid, and therefore already imply the correct requirements. In |
| addition, a sentence is added at the beginning of chapter 25 saying |
| that expressions given as conditions must evaluate to true or false in |
| a boolean context. An alternative would be to say that the type of |
| these condition expressions must be literally bool, but that would be |
| imposing a greater restriction that what the standard currently says |
| (which is convertible to bool). |
| </p> |
| <hr> |
| <a name="284"><h3>284. unportable example in 20.3.7, p6</h3></a><p><b>Section:</b> 20.5.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.comparisons"> [lib.comparisons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 26 Dec 2000</p> |
| <p>The example in 20.5.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.comparisons"> [lib.comparisons]</a>, p6 shows how to use the C |
| library function <tt>strcmp()</tt> with the function pointer adapter |
| <tt>ptr_fun()</tt>. But since it's unspecified whether the C library |
| functions have <tt>extern "C"</tt> or <tt>extern |
| "C++"</tt> linkage [17.4.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.using.linkage"> [lib.using.linkage]</a>], and since |
| function pointers with different the language linkage specifications |
| (7.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/dcl.html#dcl.link"> [dcl.link]</a>) are incompatible, whether this example is |
| well-formed is unspecified. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 20.5.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.comparisons"> [lib.comparisons]</a> paragraph 6 from:</p> |
| <blockquote> |
| <p>[<i>Example:</i></p> |
| <pre> replace_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(strcmp), "C")), "C++"); |
| </pre> |
| <p>replaces each <tt>C</tt> with <tt>C++</tt> in sequence <tt>v</tt>.</p> |
| </blockquote> |
| |
| |
| <p>to:</p> |
| <blockquote> |
| <p>[<i>Example:</i></p> |
| <pre> int compare(const char*, const char*); |
| replace_if(v.begin(), v.end(), |
| not1(bind2nd(ptr_fun(compare), "abc")), "def"); |
| </pre> |
| <p>replaces each <tt>abc</tt> with <tt>def</tt> in sequence <tt>v</tt>.</p> |
| </blockquote> |
| |
| <p>Also, remove footnote 215 in that same paragraph.</p> |
| |
| <p><i>[Copenhagen: Minor change in the proposed resolution. Since this |
| issue deals in part with C and C++ linkage, it was believed to be too |
| confusing for the strings in the example to be "C" and "C++". |
| ]</i></p> |
| |
| <p><i>[Redmond: More minor changes. Got rid of the footnote (which |
| seems to make a sweeping normative requirement, even though footnotes |
| aren't normative), and changed the sentence after the footnote so that |
| it corresponds to the new code fragment.]</i></p> |
| |
| <hr> |
| <a name="285"><h3>285. minor editorial errors in fstream ctors</h3></a><p><b>Section:</b> 27.8.1.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ifstream.cons"> [lib.ifstream.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 31 Dec 2000</p> |
| <p>27.8.1.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ifstream.cons"> [lib.ifstream.cons]</a>, p2, 27.8.1.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ofstream.cons"> [lib.ofstream.cons]</a>, p2, and |
| 27.8.1.12 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstream.cons"> [lib.fstream.cons]</a>, p2 say about the effects of each constructor: |
| </p> |
| |
| <p>... If that function returns a null pointer, calls |
| <tt>setstate(failbit)</tt> (which may throw <tt>ios_base::failure</tt>). |
| </p> |
| |
| <p>The parenthetical note doesn't apply since the ctors cannot throw an |
| exception due to the requirement in 27.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.cons"> [lib.basic.ios.cons]</a>, p3 |
| that <tt>exceptions()</tt> be initialized to <tt>ios_base::goodbit</tt>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Strike the parenthetical note from the Effects clause in each of the |
| paragraphs mentioned above. |
| </p> |
| <hr> |
| <a name="286"><h3>286. <cstdlib> requirements missing size_t typedef</h3></a><p><b>Section:</b> 25.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.c.library"> [lib.alg.c.library]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 30 Dec 2000</p> |
| <p> |
| The <cstdlib> header file contains prototypes for bsearch and |
| qsort (C++ Standard section 25.4 paragraphs 3 and 4) and other |
| prototypes (C++ Standard section 21.4 paragraph 1 table 49) that |
| require the typedef size_t. Yet size_t is not listed in the |
| <cstdlib> synopsis table 78 in section 25.4. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the type size_t to Table 78 (section 25.4) and add |
| the type size_t <cstdlib> to Table 97 (section C.2). |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>Since size_t is in <stdlib.h>, it must also be in <cstdlib>.</p> |
| <hr> |
| <a name="288"><h3>288. <cerrno> requirements missing macro EILSEQ</h3></a><p><b>Section:</b> 19.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-diagnostics.html#lib.errno"> [lib.errno]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 30 Dec 2000</p> |
| <p> |
| ISO/IEC 9899:1990/Amendment1:1994 Section 4.3 States: "The list |
| of macros defined in <errno.h> is adjusted to include a new |
| macro, EILSEQ" |
| </p> |
| |
| <p> |
| ISO/IEC 14882:1998(E) section 19.3 does not refer |
| to the above amendment. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Update Table 26 (section 19.3) "Header <cerrno> synopsis" |
| and Table 95 (section C.2) "Standard Macros" to include EILSEQ. |
| </p> |
| <hr> |
| <a name="291"><h3>291. Underspecification of set algorithms</h3></a><p><b>Section:</b> 25.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.set.operations"> [lib.alg.set.operations]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 03 Jan 2001</p> |
| <p> |
| The standard library contains four algorithms that compute set |
| operations on sorted ranges: <tt>set_union</tt>, <tt>set_intersection</tt>, |
| <tt>set_difference</tt>, and <tt>set_symmetric_difference</tt>. Each |
| of these algorithms takes two sorted ranges as inputs, and writes the |
| output of the appropriate set operation to an output range. The elements |
| in the output range are sorted. |
| </p> |
| |
| <p> |
| The ordinary mathematical definitions are generalized so that they |
| apply to ranges containing multiple copies of a given element. Two |
| elements are considered to be "the same" if, according to an |
| ordering relation provided by the user, neither one is less than the |
| other. So, for example, if one input range contains five copies of an |
| element and another contains three, the output range of <tt>set_union</tt> |
| will contain five copies, the output range of |
| <tt>set_intersection</tt> will contain three, the output range of |
| <tt>set_difference</tt> will contain two, and the output range of |
| <tt>set_symmetric_difference</tt> will contain two. |
| </p> |
| |
| <p> |
| Because two elements can be "the same" for the purposes |
| of these set algorithms, without being identical in other respects |
| (consider, for example, strings under case-insensitive comparison), |
| this raises a number of unanswered questions: |
| </p> |
| |
| <ul> |
| <li>If we're copying an element that's present in both of the |
| input ranges, which one do we copy it from?</li> |
| <li>If there are <i>n</i> copies of an element in the relevant |
| input range, and the output range will contain fewer copies (say |
| <i>m</i>) which ones do we choose? The first <i>m</i>, or the last |
| <i>m</i>, or something else?</li> |
| <li>Are these operations stable? That is, does a run of equivalent |
| elements appear in the output range in the same order as as it |
| appeared in the input range(s)?</li> |
| </ul> |
| |
| <p> |
| The standard should either answer these questions, or explicitly |
| say that the answers are unspecified. I prefer the former option, |
| since, as far as I know, all existing implementations behave the |
| same way. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following to the end of 25.3.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.set.union"> [lib.set.union]</a> paragraph 5:</p> |
| <blockquote> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to |
| each other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, then max(<i>m</i>, <i>n</i>) of these elements |
| will be copied to the output range: all <i>m</i> of these elements |
| from [first1, last1), and the last max(<i>n-m</i>, 0) of them from |
| [first2, last2), in that order. |
| </blockquote> |
| |
| <p>Add the following to the end of 25.3.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.set.intersection"> [lib.set.intersection]</a> paragraph 5:</p> |
| <blockquote> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to each |
| other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, the first min(<i>m</i>, <i>n</i>) of those |
| elements from [first1, last1) are copied to the output range. |
| </blockquote> |
| |
| <p>Add a new paragraph, <b>Notes</b>, after 25.3.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.set.difference"> [lib.set.difference]</a> |
| paragraph 4:</p> |
| <blockquote> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to each |
| other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, the last max(<i>m-n</i>, 0) elements from |
| [first1, last1) are copied to the output range. |
| </blockquote> |
| |
| <p>Add a new paragraph, <b>Notes</b>, after 25.3.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.set.symmetric.difference"> [lib.set.symmetric.difference]</a> |
| paragraph 4:</p> |
| <blockquote> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to |
| each other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, then |<i>m - n</i>| of those elements will be |
| copied to the output range: the last <i>m - n</i> of these elements |
| from [first1, last1) if <i>m</i> > <i>n</i>, and the last <i>n - |
| m</i> of these elements from [first2, last2) if <i>m</i> < <i>n</i>. |
| </blockquote> |
| |
| <p><i>[Santa Cruz: it's believed that this language is clearer than |
| what's in the Standard. However, it's also believed that the |
| Standard may already make these guarantees (although not quite in |
| these words). Bill and Howard will check and see whether they think |
| that some or all of these changes may be redundant. If so, we may |
| close this issue as NAD.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>For simple cases, these descriptions are equivalent to what's |
| already in the Standard. For more complicated cases, they describe |
| the behavior of existing implementations.</p> |
| <hr> |
| <a name="292"><h3>292. effects of a.copyfmt (a)</h3></a><p><b>Section:</b> 27.4.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.basic.ios.members"> [lib.basic.ios.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 05 Jan 2001</p> |
| <p>The Effects clause of the member function <tt>copyfmt()</tt> in |
| 27.4.4.2, p15 doesn't consider the case where the left-hand side |
| argument is identical to the argument on the right-hand side, that is |
| <tt>(this == &rhs)</tt>. If the two arguments are identical there |
| is no need to copy any of the data members or call any callbacks |
| registered with <tt>register_callback()</tt>. Also, as Howard Hinnant |
| points out in message c++std-lib-8149 it appears to be incorrect to |
| allow the object to fire <tt>erase_event</tt> followed by |
| <tt>copyfmt_event</tt> since the callback handling the latter event |
| may inadvertently attempt to access memory freed by the former. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the Effects clause in 27.4.4.2, p15 from</p> |
| |
| <blockquote> |
| <b>-15- Effects:</b>Assigns to the member objects of <tt>*this</tt> |
| the corresponding member objects of <tt>rhs</tt>, except that... |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <b>-15- Effects:</b>If <tt>(this == &rhs)</tt> does nothing. Otherwise |
| assigns to the member objects of <tt>*this</tt> the corresponding member |
| objects of <tt>rhs</tt>, except that... |
| </blockquote> |
| <hr> |
| <a name="294"><h3>294. User defined macros and standard headers</h3></a><p><b>Section:</b> 17.4.3.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.macro.names"> [lib.macro.names]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> James Kanze <b>Date:</b> 11 Jan 2001</p> |
| <p>Paragraph 2 of 17.4.3.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.macro.names"> [lib.macro.names]</a> reads: "A |
| translation unit that includes a header shall not contain any macros |
| that define names declared in that header." As I read this, it |
| would mean that the following program is legal:</p> |
| |
| <pre> #define npos 3.14 |
| #include <sstream> |
| </pre> |
| |
| <p>since npos is not defined in <sstream>. It is, however, defined |
| in <string>, and it is hard to imagine an implementation in |
| which <sstream> didn't include <string>.</p> |
| |
| <p>I think that this phrase was probably formulated before it was |
| decided that a standard header may freely include other standard |
| headers. The phrase would be perfectly appropriate for C, for |
| example. In light of 17.4.4.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.headers"> [lib.res.on.headers]</a> paragraph 1, however, |
| it isn't stringent enough.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>For 17.4.3.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.macro.names"> [lib.macro.names]</a>, replace the current wording, which reads:</p> |
| <blockquote> |
| <p>Each name defined as a macro in a header is reserved to the |
| implementation for any use if the translation unit includes |
| the header.168)</p> |
| |
| <p>A translation unit that includes a header shall not contain any |
| macros that define names declared or defined in that header. Nor shall |
| such a translation unit define macros for names lexically |
| identical to keywords.</p> |
| |
| <p>168) It is not permissible to remove a library macro definition by |
| using the #undef directive.</p> |
| </blockquote> |
| |
| <p>with the wording:</p> |
| |
| <blockquote> |
| <p>A translation unit that includes a standard library header shall not |
| #define or #undef names declared in any standard library header.</p> |
| |
| <p>A translation unit shall not #define or #undef names lexically |
| identical to keywords.</p> |
| </blockquote> |
| |
| <p><i>[Lillehammer: Beman provided new wording]</i></p> |
| |
| <hr> |
| <a name="295"><h3>295. Is abs defined in <cmath>?</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#WP">WP</a> <b>Submitter:</b> Jens Maurer <b>Date:</b> 12 Jan 2001</p> |
| <p> |
| Table 80 lists the contents of the <cmath> header. It does not |
| list <tt>abs()</tt>. However, 26.5, paragraph 6, which lists added |
| signatures present in <cmath>, does say that several overloads |
| of <tt>abs()</tt> should be defined in <cmath>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add <tt>abs</tt> to Table 80. Also, remove the parenthetical list |
| of functions "(abs(), div(), rand(), srand())" from 26.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.numarray"> [lib.numarray]</a>, |
| paragraph 1. |
| </p> |
| |
| <p><i>[Copenhagen: Modified proposed resolution so that it also gets |
| rid of that vestigial list of functions in paragraph 1.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>All this DR does is fix a typo; it's uncontroversial. A |
| separate question is whether we're doing the right thing in |
| putting some overloads in <cmath> that we aren't also |
| putting in <cstdlib>. That's issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>.</p> |
| <hr> |
| <a name="297"><h3>297. const_mem_fun_t<>::argument_type should be const T*</h3></a><p><b>Section:</b> 20.5.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.logical.operations"> [lib.logical.operations]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 6 Jan 2001</p> |
| <p>The class templates <tt>const_mem_fun_t</tt> in 20.5.8, p8 and |
| <tt>const_mem_fun1_t</tt> |
| in 20.5.8, p9 derive from <tt>unary_function<T*, S></tt>, and |
| <tt>binary_function<T*, |
| A, S></tt>, respectively. Consequently, their <tt>argument_type</tt>, and |
| <tt>first_argument_type</tt> |
| members, respectively, are both defined to be <tt>T*</tt> (non-const). |
| However, their function call member operator takes a <tt>const T*</tt> |
| argument. It is my opinion that <tt>argument_type</tt> should be <tt>const |
| T*</tt> instead, so that one can easily refer to it in generic code. The |
| example below derived from existing code fails to compile due to the |
| discrepancy: |
| </p> |
| |
| <p><tt>template <class T></tt> |
| <br><tt>void foo (typename T::argument_type arg) // #1</tt> |
| <br><tt>{</tt> |
| <br><tt> typename T::result_type (T::*pf) (typename |
| T::argument_type) |
| const = // #2</tt> |
| <br><tt> &T::operator();</tt> |
| <br><tt>}</tt> |
| </p> |
| |
| <p><tt>struct X { /* ... */ };</tt></p> |
| |
| <p><tt>int main ()</tt> |
| <br><tt>{</tt> |
| <br><tt> const X x;</tt> |
| <br><tt> foo<std::const_mem_fun_t<void, X> |
| >(&x); |
| // #3</tt> |
| <br><tt>}</tt> |
| </p> |
| |
| <p>#1 <tt>foo()</tt> takes a plain unqualified <tt>X*</tt> as an argument |
| <br>#2 the type of the pointer is incompatible with the type of the member |
| function |
| <br>#3 the address of a constant being passed to a function taking a non-const |
| <tt>X*</tt> |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the top portion of the definition of the class template |
| const_mem_fun_t in 20.5.8, p8 |
| </p> |
| <p><tt>template <class S, class T> class const_mem_fun_t</tt> |
| <br><tt> : public |
| unary_function<T*, S> {</tt> |
| </p> |
| <p>with</p> |
| <p><tt>template <class S, class T> class const_mem_fun_t</tt> |
| <br><tt> : public |
| unary_function<<b>const</b> T*, S> {</tt> |
| </p> |
| <p>Also replace the top portion of the definition of the class template |
| const_mem_fun1_t in 20.5.8, p9</p> |
| <p><tt>template <class S, class T, class A> class const_mem_fun1_t</tt> |
| <br><tt> : public |
| binary_function<T*, A, S> {</tt> |
| </p> |
| <p>with</p> |
| <p><tt>template <class S, class T, class A> class const_mem_fun1_t</tt> |
| <br><tt> : public |
| binary_function<<b>const</b> T*, A, S> {</tt> |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>This is simply a contradiction: the <tt>argument_type</tt> typedef, |
| and the argument type itself, are not the same.</p> |
| <hr> |
| <a name="298"><h3>298. ::operator delete[] requirement incorrect/insufficient</h3></a><p><b>Section:</b> 18.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete.array"> [lib.new.delete.array]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> John A. Pedretti <b>Date:</b> 10 Jan 2001</p> |
| <p> |
| The default behavior of <tt>operator delete[]</tt> described in 18.5.1.2, p12 - |
| namely that for non-null value of <i>ptr</i>, the operator reclaims storage |
| allocated by the earlier call to the default <tt>operator new[]</tt> - is not |
| correct in all cases. Since the specified <tt>operator new[]</tt> default |
| behavior is to call <tt>operator new</tt> (18.5.1.2, p4, p8), which can be |
| replaced, along with <tt>operator delete</tt>, by the user, to implement their |
| own memory management, the specified default behavior of<tt> operator |
| delete[]</tt> must be to call <tt>operator delete</tt>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 18.5.1.2, p12 from</p> |
| <blockquote> |
| <b>-12-</b> <b>Default behavior:</b> |
| <ul> |
| <li> |
| For a null value of <i><tt>ptr</tt></i> , does nothing. |
| </li> |
| <li> |
| Any other value of <i><tt>ptr</tt></i> shall be a value returned |
| earlier by a call to the default <tt>operator new[](std::size_t)</tt>. |
| [Footnote: The value must not have been invalidated by an intervening |
| call to <tt>operator delete[](void*)</tt> (17.4.3.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.arguments"> [lib.res.on.arguments]</a>). |
| --- end footnote] |
| For such a non-null value of <i><tt>ptr</tt></i> , reclaims storage |
| allocated by the earlier call to the default <tt>operator new[]</tt>. |
| </li> |
| </ul> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <b>-12-</b> <b>Default behavior: </b>Calls <tt>operator |
| delete(</tt><i>ptr</i>) |
| or <tt>operator delete(<i>ptr</i>, std::nothrow)</tt> respectively. |
| </blockquote> |
| <p>and expunge paragraph 13.</p> |
| <hr> |
| <a name="300"><h3>300. list::merge() specification incomplete</h3></a><p><b>Section:</b> 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> John Pedretti <b>Date:</b> 23 Jan 2001</p> |
| <p> |
| The "Effects" clause for list::merge() (23.2.2.4, p23) |
| appears to be incomplete: it doesn't cover the case where the argument |
| list is identical to *this (i.e., this == &x). The requirement in the |
| note in p24 (below) is that x be empty after the merge which is surely |
| unintended in this case. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a>, replace paragraps 23-25 with:</p> |
| <blockquote> |
| <p> |
| 23 Effects: if (&x == this) does nothing; otherwise, merges the two |
| sorted ranges [begin(), end()) and [x.begin(), x.end()). The result |
| is a range in which the elements will be sorted in non-decreasing |
| order according to the ordering defined by comp; that is, for every |
| iterator i in the range other than the first, the condition comp(*i, |
| *(i - 1)) will be false. |
| </p> |
| |
| <p> |
| 24 Notes: Stable: if (&x != this), then for equivalent elements in the |
| two original ranges, the elements from the original range [begin(), |
| end()) always precede the elements from the original range [x.begin(), |
| x.end()). If (&x != this) the range [x.begin(), x.end()) is empty |
| after the merge. |
| </p> |
| |
| <p> |
| 25 Complexity: At most size() + x.size() - 1 applications of comp if |
| (&x ! = this); otherwise, no applications of comp are performed. If |
| an exception is thrown other than by a comparison there are no |
| effects. |
| </p> |
| |
| </blockquote> |
| |
| <p><i>[Copenhagen: The original proposed resolution did not fix all of |
| the problems in 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a>, p22-25. Three different |
| paragraphs (23, 24, 25) describe the effects of <tt>merge</tt>. |
| Changing p23, without changing the other two, appears to introduce |
| contradictions. Additionally, "merges the argument list into the |
| list" is excessively vague.]</i></p> |
| |
| <p><i>[Post-Curaçao: Robert Klarer provided new wording.]</i></p> |
| |
| <hr> |
| <a name="301"><h3>301. basic_string template ctor effects clause omits allocator argument</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 27 Jan 2001</p> |
| <p> |
| The effects clause for the basic_string template ctor in 21.3.1, p15 |
| leaves out the third argument of type Allocator. I believe this to be |
| a mistake. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace</p> |
| |
| <blockquote> |
| <p><b>-15- Effects:</b> If <i><tt>InputIterator</tt></i> is an integral |
| type, equivalent to</p> |
| |
| <blockquote><tt>basic_string(static_cast<size_type>(begin), |
| static_cast<value_type>(end))</tt></blockquote> |
| </blockquote> |
| |
| <p>with</p> |
| |
| <blockquote> |
| <p><b>-15- Effects:</b> If <i><tt>InputIterator</tt></i> is an integral |
| type, equivalent to</p> |
| |
| <blockquote><tt>basic_string(static_cast<size_type>(begin), |
| static_cast<value_type>(end), <b>a</b>)</tt></blockquote> |
| </blockquote> |
| <hr> |
| <a name="303"><h3>303. Bitset input operator underspecified</h3></a><p><b>Section:</b> 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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 5 Feb 2001</p> |
| <p> |
| In 23.3.5.3, we are told that <tt>bitset</tt>'s input operator |
| "Extracts up to <i>N</i> (single-byte) characters from |
| <i>is</i>.", where <i>is</i> is a stream of type |
| <tt>basic_istream<charT, traits></tt>. |
| </p> |
| |
| <p> |
| The standard does not say what it means to extract single byte |
| characters from a stream whose character type, <tt>charT</tt>, is in |
| general not a single-byte character type. Existing implementations |
| differ. |
| </p> |
| |
| <p> |
| A reasonable solution will probably involve <tt>widen()</tt> and/or |
| <tt>narrow()</tt>, since they are the supplied mechanism for |
| converting a single character between <tt>char</tt> and |
| arbitrary <tt>charT</tt>. |
| </p> |
| |
| <p>Narrowing the input characters is not the same as widening the |
| literals <tt>'0'</tt> and <tt>'1'</tt>, because there may be some |
| locales in which more than one wide character maps to the narrow |
| character <tt>'0'</tt>. Narrowing means that alternate |
| representations may be used for bitset input, widening means that |
| they may not be.</p> |
| |
| <p>Note that for numeric input, <tt>num_get<></tt> |
| (22.2.2.1.2/8) compares input characters to widened version of narrow |
| character literals.</p> |
| |
| <p>From Pete Becker, in c++std-lib-8224:</p> |
| <blockquote> |
| <p> |
| Different writing systems can have different representations for the |
| digits that represent 0 and 1. For example, in the Unicode representation |
| of the Devanagari script (used in many of the Indic languages) the digit 0 |
| is 0x0966, and the digit 1 is 0x0967. Calling narrow would translate those |
| into '0' and '1'. But Unicode also provides the ASCII values 0x0030 and |
| 0x0031 for for the Latin representations of '0' and '1', as well as code |
| points for the same numeric values in several other scripts (Tamil has no |
| character for 0, but does have the digits 1-9), and any of these values |
| would also be narrowed to '0' and '1'. |
| </p> |
| |
| <p>...</p> |
| |
| <p> |
| It's fairly common to intermix both native and Latin |
| representations of numbers in a document. So I think the rule has to be |
| that if a wide character represents a digit whose value is 0 then the bit |
| should be cleared; if it represents a digit whose value is 1 then the bit |
| should be set; otherwise throw an exception. So in a Devanagari locale, |
| both 0x0966 and 0x0030 would clear the bit, and both 0x0967 and 0x0031 |
| would set it. Widen can't do that. It would pick one of those two values, |
| and exclude the other one. |
| </p> |
| |
| </blockquote> |
| |
| <p>From Jens Maurer, in c++std-lib-8233:</p> |
| |
| <blockquote> |
| <p> |
| Whatever we decide, I would find it most surprising if |
| bitset conversion worked differently from int conversion |
| with regard to alternate local representations of |
| numbers. |
| </p> |
| |
| <p>Thus, I think the options are:</p> |
| <ul> |
| <li> Have a new defect issue for 22.2.2.1.2/8 so that it will |
| require the use of narrow().</li> |
| |
| <li> Have a defect issue for bitset() which describes clearly |
| that widen() is to be used.</li> |
| </ul> |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Replace the first two sentences of paragraph 5 with:</p> |
| |
| <blockquote> |
| Extracts up to <i>N</i> characters from <i>is</i>. Stores these |
| characters in a temporary object <i>str</i> of type |
| <tt>basic_string<charT, traits></tt>, then evaluates the |
| expression <tt><i>x</i> = bitset<N>(<i>str</i>)</tt>. |
| </blockquote> |
| |
| <p>Replace the third bullet item in paragraph 5 with:</p> |
| <ul><li> |
| the next input character is neither <tt><i>is</i>.widen(0)</tt> |
| nor <tt><i>is</i>.widen(1)</tt> (in which case the input character |
| is not extracted). |
| </li></ul> |
| |
| <p><b>Rationale:</b></p> |
| <p>Input for <tt>bitset</tt> should work the same way as numeric |
| input. Using <tt>widen</tt> does mean that alternative digit |
| representations will not be recognized, but this was a known |
| consequence of the design choice.</p> |
| <hr> |
| <a name="305"><h3>305. Default behavior of codecvt<wchar_t, char, mbstate_t>::length()</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#WP">WP</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 24 Jan 2001</p> |
| <p>22.2.1.5/3 introduces codecvt in part with:</p> |
| |
| <blockquote> |
| codecvt<wchar_t,char,mbstate_t> converts between the native |
| character sets for tiny and wide characters. Instantiations on |
| mbstate_t perform conversion between encodings known to the library |
| implementor. |
| </blockquote> |
| |
| <p>But 22.2.1.5.2/10 describes do_length in part with:</p> |
| |
| <blockquote> |
| ... codecvt<wchar_t, char, mbstate_t> ... return(s) the lesser of max and |
| (from_end-from). |
| </blockquote> |
| |
| <p> |
| The semantics of do_in and do_length are linked. What one does must |
| be consistent with what the other does. 22.2.1.5/3 leads me to |
| believe that the vendor is allowed to choose the algorithm that |
| codecvt<wchar_t,char,mbstate_t>::do_in performs so that it makes |
| his customers happy on a given platform. But 22.2.1.5.2/10 explicitly |
| says what codecvt<wchar_t,char,mbstate_t>::do_length must |
| return. And thus indirectly specifies the algorithm that |
| codecvt<wchar_t,char,mbstate_t>::do_in must perform. I believe |
| that this is not what was intended and is a defect. |
| </p> |
| |
| <p>Discussion from the -lib reflector: |
| |
| <br>This proposal would have the effect of making the semantics of |
| all of the virtual functions in <tt>codecvt<wchar_t, char, |
| mbstate_t></tt> implementation specified. Is that what we want, or |
| do we want to mandate specific behavior for the base class virtuals |
| and leave the implementation specified behavior for the codecvt_byname |
| derived class? The tradeoff is that former allows implementors to |
| write a base class that actually does something useful, while the |
| latter gives users a way to get known and specified---albeit |
| useless---behavior, and is consistent with the way the standard |
| handles other facets. It is not clear what the original intention |
| was.</p> |
| |
| <p> |
| Nathan has suggest a compromise: a character that is a widened version |
| of the characters in the basic execution character set must be |
| converted to a one-byte sequence, but there is no such requirement |
| for characters that are not part of the basic execution character set. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 22.2.1.5.2/5 from: |
| </p> |
| <p> |
| The instantiations required in Table 51 (lib.locale.category), namely |
| codecvt<wchar_t,char,mbstate_t> and |
| codecvt<char,char,mbstate_t>, store no characters. Stores no more |
| than (to_limit-to) destination elements. It always leaves the to_next |
| pointer pointing one beyond the last element successfully stored. |
| </p> |
| <p> |
| to: |
| </p> |
| <p> |
| Stores no more than (to_limit-to) destination elements, and leaves the |
| to_next pointer pointing one beyond the last element successfully |
| stored. codecvt<char,char,mbstate_t> stores no characters. |
| </p> |
| |
| <p>Change 22.2.1.5.2/10 from:</p> |
| |
| <blockquote> |
| -10- Returns: (from_next-from) where from_next is the largest value in |
| the range [from,from_end] such that the sequence of values in the |
| range [from,from_next) represents max or fewer valid complete |
| characters of type internT. The instantiations required in Table 51 |
| (21.1.1.1.1), namely codecvt<wchar_t, char, mbstate_t> and |
| codecvt<char, char, mbstate_t>, return the lesser of max and |
| (from_end-from). |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| -10- Returns: (from_next-from) where from_next is the largest value in |
| the range [from,from_end] such that the sequence of values in the range |
| [from,from_next) represents max or fewer valid complete characters of |
| type internT. The instantiation codecvt<char, char, mbstate_t> returns |
| the lesser of max and (from_end-from). |
| </blockquote> |
| |
| <p><i>[Redmond: Nathan suggested an alternative resolution: same as |
| above, but require that, in the default encoding, a character from the |
| basic execution character set would map to a single external |
| character. The straw poll was 8-1 in favor of the proposed |
| resolution.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The default encoding should be whatever users of a given platform |
| would expect to be the most natural. This varies from platform to |
| platform. In many cases there is a preexisting C library, and users |
| would expect the default encoding to be whatever C uses in the default |
| "C" locale. We could impose a guarantee like the one Nathan suggested |
| (a character from the basic execution character set must map to a |
| single external character), but this would rule out important |
| encodings that are in common use: it would rule out JIS, for |
| example, and it would rule out a fixed-width encoding of UCS-4.</p> |
| |
| <p><i>[Curaçao: fixed rationale typo at the request of Ichiro Koshida; |
| "shift-JIS" changed to "JIS".]</i></p> |
| |
| <hr> |
| <a name="306"><h3>306. offsetof macro and non-POD types</h3></a><p><b>Section:</b> 18.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.support.types"> [lib.support.types]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 21 Feb 2001</p> |
| <p>Spliced together from reflector messages c++std-lib-8294 and -8295:</p> |
| |
| <p>18.1, paragraph 5, reads: "The macro <tt>offsetof</tt> |
| accepts a restricted set of <i>type</i> arguments in this |
| International Standard. <i>type</i> shall be a POD structure or a POD |
| union (clause 9). The result of applying the offsetof macro to a field |
| that is a static data member or a function member is |
| undefined."</p> |
| |
| <p>For the POD requirement, it doesn't say "no diagnostic |
| required" or "undefined behavior". I read 1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/intro.html#intro.compliance"> [intro.compliance]</a>, paragraph 1, to mean that a diagnostic is required. |
| It's not clear whether this requirement was intended. While it's |
| possible to provide such a diagnostic, the extra complication doesn't |
| seem to add any value. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 18.1, paragraph 5, to "If <i>type</i> is not a POD |
| structure or a POD union the results are undefined."</p> |
| |
| <p><i>[Copenhagen: straw poll was 7-4 in favor. It was generally |
| agreed that requiring a diagnostic was inadvertent, but some LWG |
| members thought that diagnostics should be required whenever |
| possible.]</i></p> |
| |
| <hr> |
| <a name="307"><h3>307. Lack of reference typedefs in container adaptors</h3></a><p><b>Section:</b> 23.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list"> [lib.list]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 13 Mar 2001</p> |
| |
| <p>From reflector message c++std-lib-8330. See also lib-8317.</p> |
| |
| <p> |
| The standard is currently inconsistent in 23.2.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.capacity"> [lib.list.capacity]</a> |
| paragraph 1 and 23.2.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.modifiers"> [lib.list.modifiers]</a> paragraph 1. |
| 23.2.3.3/1, for example, says: |
| </p> |
| |
| <blockquote> |
| -1- Any sequence supporting operations back(), push_back() and pop_back() |
| can be used to instantiate stack. In particular, vector (lib.vector), list |
| (lib.list) and deque (lib.deque) can be used. |
| </blockquote> |
| |
| <p>But this is false: vector<bool> can not be used, because the |
| container adaptors return a T& rather than using the underlying |
| container's reference type.</p> |
| |
| <p>This is a contradiction that can be fixed by:</p> |
| |
| <ol> |
| <li>Modifying these paragraphs to say that vector<bool> |
| is an exception.</li> |
| <li>Removing the vector<bool> specialization.</li> |
| <li>Changing the return types of stack and priority_queue to use |
| reference typedef's.</li> |
| </ol> |
| |
| <p> |
| I propose 3. This does not preclude option 2 if we choose to do it |
| later (see issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#96">96</a>); the issues are independent. Option |
| 3 offers a small step towards support for proxied containers. This |
| small step fixes a current contradiction, is easy for vendors to |
| implement, is already implemented in at least one popular lib, and |
| does not break any code. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Summary: Add reference and const_reference typedefs to queue, |
| priority_queue and stack. Change return types of "value_type&" to |
| "reference". Change return types of "const value_type&" to |
| "const_reference". Details:</p> |
| |
| <p>Change 23.2.3.1/1 from:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit queue(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| value_type& front() { return c.front(); } |
| const value_type& front() const { return c.front(); } |
| value_type& back() { return c.back(); } |
| const value_type& back() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_front(); } |
| }; |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::reference reference; |
| typedef typename Container::const_reference const_reference; |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit queue(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| reference front() { return c.front(); } |
| const_reference front() const { return c.front(); } |
| reference back() { return c.back(); } |
| const_reference back() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_front(); } |
| }; |
| </pre> |
| |
| <p>Change 23.2.3.2/1 from:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = vector<T>, |
| class Compare = less<typename Container::value_type> > |
| class priority_queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| Compare comp; |
| |
| public: |
| explicit priority_queue(const Compare& x = Compare(), |
| const Container& = Container()); |
| template <class InputIterator> |
| priority_queue(InputIterator first, InputIterator last, |
| const Compare& x = Compare(), |
| const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| const value_type& top() const { return c.front(); } |
| void push(const value_type& x); |
| void pop(); |
| }; |
| // no equality is provided |
| } |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = vector<T>, |
| class Compare = less<typename Container::value_type> > |
| class priority_queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::reference reference; |
| typedef typename Container::const_reference const_reference; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| Compare comp; |
| |
| public: |
| explicit priority_queue(const Compare& x = Compare(), |
| const Container& = Container()); |
| template <class InputIterator> |
| priority_queue(InputIterator first, InputIterator last, |
| const Compare& x = Compare(), |
| const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| const_reference top() const { return c.front(); } |
| void push(const value_type& x); |
| void pop(); |
| }; |
| // no equality is provided |
| } |
| </pre> |
| |
| <p>And change 23.2.3.3/1 from:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class stack { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit stack(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| value_type& top() { return c.back(); } |
| const value_type& top() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_back(); } |
| }; |
| |
| template <class T, class Container> |
| bool operator==(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator< (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator!=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator> (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator>=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator<=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| } |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class stack { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::reference reference; |
| typedef typename Container::const_reference const_reference; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit stack(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| reference top() { return c.back(); } |
| const_reference top() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_back(); } |
| }; |
| |
| template <class T, class Container> |
| bool operator==(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator< (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator!=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator> (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator>=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator<=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| } |
| </pre> |
| |
| <p><i>[Copenhagen: This change was discussed before the IS was released |
| and it was deliberately not adopted. Nevertheless, the LWG believes |
| (straw poll: 10-2) that it is a genuine defect.]</i></p> |
| |
| <hr> |
| <a name="308"><h3>308. Table 82 mentions unrelated headers</h3></a><p><b>Section:</b> 27 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 15 Mar 2001</p> |
| <p> |
| Table 82 in section 27 mentions the header <cstdlib> for String |
| streams (27.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.string.streams"> [lib.string.streams]</a>) and the headers <cstdio> and |
| <cwchar> for File streams (27.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.file.streams"> [lib.file.streams]</a>). It's not clear |
| why these headers are mentioned in this context since they do not |
| define any of the library entities described by the |
| subclauses. According to 17.4.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.contents"> [lib.contents]</a>, only such headers |
| are to be listed in the summary. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove <cstdlib> and <cwchar> from |
| Table 82.</p> |
| |
| <p><i>[Copenhagen: changed the proposed resolution slightly. The |
| original proposed resolution also said to remove <cstdio> from |
| Table 82. However, <cstdio> is mentioned several times within |
| section 27.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.file.streams"> [lib.file.streams]</a>, including 27.8.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.c.files"> [lib.c.files]</a>.]</i></p> |
| |
| <hr> |
| <a name="310"><h3>310. Is errno a macro?</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>, 19.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-diagnostics.html#lib.errno"> [lib.errno]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 21 Mar 2001</p> |
| <p> |
| Exactly how should errno be declared in a conforming C++ header? |
| </p> |
| |
| <p> |
| The C standard says in 7.1.4 that it is unspecified whether errno is a |
| macro or an identifier with external linkage. In some implementations |
| it can be either, depending on compile-time options. (E.g., on |
| Solaris in multi-threading mode, errno is a macro that expands to a |
| function call, but is an extern int otherwise. "Unspecified" allows |
| such variability.) |
| </p> |
| |
| <p>The C++ standard:</p> |
| <ul> |
| <li>17.4.1.2 says in a note that errno must be macro in C. (false)</li> |
| <li>17.4.3.1.3 footnote 166 says errno is reserved as an external |
| name (true), and implies that it is an identifier.</li> |
| <li>19.3 simply lists errno as a macro (by what reasoning?) and goes |
| on to say that the contents of of C++ <errno.h> are the |
| same as in C, begging the question.</li> |
| <li>C.2, table 95 lists errno as a macro, without comment.</li> |
| </ul> |
| |
| <p>I find no other references to errno.</p> |
| |
| <p>We should either explicitly say that errno must be a macro, even |
| though it need not be a macro in C, or else explicitly leave it |
| unspecified. We also need to say something about namespace std. |
| A user who includes <cerrno> needs to know whether to write |
| <tt>errno</tt>, or <tt>::errno</tt>, or <tt>std::errno</tt>, or |
| else <cerrno> is useless.</p> |
| |
| <p>Two acceptable fixes:</p> |
| <ul> |
| <li><p>errno must be a macro. This is trivially satisfied by adding<br> |
| #define errno (::std::errno)<br> |
| to the headers if errno is not already a macro. You then always |
| write errno without any scope qualification, and it always expands |
| to a correct reference. Since it is always a macro, you know to |
| avoid using errno as a local identifer.</p></li> |
| <li><p>errno is in the global namespace. This fix is inferior, because |
| ::errno is not guaranteed to be well-formed.</p></li> |
| </ul> |
| |
| <p><i>[ |
| This issue was first raised in 1999, but it slipped through |
| the cracks. |
| ]</i></p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the Note in section 17.4.1.2p5 from</p> |
| |
| <blockquote> |
| Note: the names defined as macros in C include the following: |
| assert, errno, offsetof, setjmp, va_arg, va_end, and va_start. |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| Note: the names defined as macros in C include the following: |
| assert, offsetof, setjmp, va_arg, va_end, and va_start. |
| </blockquote> |
| |
| <p>In section 19.3, change paragraph 2 from</p> |
| |
| <blockquote> |
| The contents are the same as the Standard C library header |
| <errno.h>. |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| The contents are the same as the Standard C library header |
| <errno.h>, except that errno shall be defined as a macro. |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>C++ must not leave it up to the implementation to decide whether or |
| not a name is a macro; it must explicitly specify exactly which names |
| are required to be macros. The only one that really works is for it |
| to be a macro.</p> |
| |
| <p><i>[Curaçao: additional rationale added.]</i></p> |
| |
| <hr> |
| <a name="311"><h3>311. Incorrect wording in basic_ostream class synopsis</h3></a><p><b>Section:</b> 27.6.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream"> [lib.ostream]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 21 Mar 2001</p> |
| |
| <p>In 27.6.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream"> [lib.ostream]</a>, the synopsis of class basic_ostream says:</p> |
| |
| <pre> // partial specializationss |
| template<class traits> |
| basic_ostream<char,traits>& operator<<( basic_ostream<char,traits>&, |
| const char * ); |
| </pre> |
| |
| <p>Problems:</p> |
| <ul> |
| <li>Too many 's's at the end of "specializationss" </li> |
| <li>This is an overload, not a partial specialization</li> |
| </ul> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In the synopsis in 27.6.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream"> [lib.ostream]</a>, remove the |
| <i>// partial specializationss</i> comment. Also remove the same |
| comment (correctly spelled, but still incorrect) from the synopsis in |
| 27.6.2.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a>. |
| </p> |
| |
| <p><i>[ |
| Pre-Redmond: added 27.6.2.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a> because of Martin's |
| comment in c++std-lib-8939. |
| ]</i></p> |
| |
| <hr> |
| <a name="312"><h3>312. Table 27 is missing headers</h3></a><p><b>Section:</b> 20 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.utilities"> [lib.utilities]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 29 Mar 2001</p> |
| <p>Table 27 in section 20 lists the header <memory> (only) for |
| Memory (lib.memory) but neglects to mention the headers |
| <cstdlib> and <cstring> that are discussed in 20.4.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.rel"> [lib.meta.rel]</a>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add <cstdlib> and <cstring> to Table 27, in the same row |
| as <memory>.</p> |
| <hr> |
| <a name="315"><h3>315. Bad "range" in list::unique complexity</h3></a><p><b>Section:</b> 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 1 May 2001</p> |
| <p> |
| 23.2.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.special"> [lib.deque.special]</a>, Para 21 describes the complexity of |
| list::unique as: "If the range (last - first) is not empty, exactly |
| (last - first) -1 applications of the corresponding predicate, |
| otherwise no applications of the predicate)". |
| </p> |
| |
| <p> |
| "(last - first)" is not a range. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the "range" from (last - first) to [first, last). |
| </p> |
| <hr> |
| <a name="316"><h3>316. Vague text in Table 69</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 4 May 2001</p> |
| <p>Table 69 says this about a_uniq.insert(t):</p> |
| |
| <blockquote> |
| inserts t if and only if there is no element in the container with key |
| equivalent to the key of t. The bool component of the returned pair |
| indicates whether the insertion takes place and the iterator component of the |
| pair points to the element with key equivalent to the key of t. |
| </blockquote> |
| |
| <p>The description should be more specific about exactly how the bool component |
| indicates whether the insertion takes place.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the text in question to</p> |
| |
| <blockquote> |
| ...The bool component of the returned pair is true if and only if the insertion |
| takes place... |
| </blockquote> |
| <hr> |
| <a name="317"><h3>317. Instantiation vs. specialization of facets</h3></a><p><b>Section:</b> 22 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.localization"> [lib.localization]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 4 May 2001</p> |
| <p> |
| The localization section of the standard refers to specializations of |
| the facet templates as instantiations even though the required facets |
| are typically specialized rather than explicitly (or implicitly) |
| instantiated. In the case of ctype<char> and |
| ctype_byname<char> (and the wchar_t versions), these facets are |
| actually required to be specialized. The terminology should be |
| corrected to make it clear that the standard doesn't mandate explicit |
| instantiation (the term specialization encompasses both explicit |
| instantiations and specializations). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In the following paragraphs, replace all occurrences of the word |
| instantiation or instantiations with specialization or specializations, |
| respectively: |
| </p> |
| |
| <blockquote> |
| 22.1.1.1.1, p4, Table 52, 22.2.1.1, p2, 22.2.1.5, p3, 22.2.1.5.1, p5, |
| 22.2.1.5.2, p10, 22.2.2, p2, 22.2.3.1, p1, 22.2.3.1.2, p1, p2 and p3, |
| 22.2.4.1, p1, 22.2.4.1.2, p1, 22,2,5, p1, 22,2,6, p2, 22.2.6.3.2, p7, and |
| Footnote 242. |
| </blockquote> |
| |
| <p>And change the text in 22.1.1.1.1, p4 from</p> |
| |
| <blockquote> |
| An implementation is required to provide those instantiations |
| for facet templates identified as members of a category, and |
| for those shown in Table 52: |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| An implementation is required to provide those specializations... |
| </blockquote> |
| |
| <p><i>[Nathan will review these changes, and will look for places where |
| explicit specialization is necessary.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>This is a simple matter of outdated language. The language to |
| describe templates was clarified during the standardization process, |
| but the wording in clause 22 was never updated to reflect that |
| change.</p> |
| <hr> |
| <a name="318"><h3>318. Misleading comment in definition of numpunct_byname</h3></a><p><b>Section:</b> 22.2.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.numpunct.byname"> [lib.locale.numpunct.byname]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 May 2001</p> |
| <p>The definition of the numpunct_byname template contains the following |
| comment:</p> |
| |
| <pre> namespace std { |
| template <class charT> |
| class numpunct_byname : public numpunct<charT> { |
| // this class is specialized for char and wchar_t. |
| ... |
| </pre> |
| |
| <p>There is no documentation of the specializations and it seems |
| conceivable that an implementation will not explicitly specialize the |
| template at all, but simply provide the primary template.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the comment from the text in 22.2.3.2 and from the proposed |
| resolution of library issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#228">228</a>.</p> |
| <hr> |
| <a name="319"><h3>319. Storage allocation wording confuses "Required behavior", "Requires"</h3></a><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>, 18.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete.array"> [lib.new.delete.array]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 15 May 2001</p> |
| <p>The standard specifies 17.3.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.structure.specifications"> [lib.structure.specifications]</a> that "Required |
| behavior" elements describe "the semantics of a function definition |
| provided by either the implementation or a C++ program."</p> |
| |
| <p>The standard specifies 17.3.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.structure.specifications"> [lib.structure.specifications]</a> that "Requires" |
| elements describe "the preconditions for calling the function."</p> |
| |
| <p>In the sections noted below, the current wording specifies |
| "Required Behavior" for what are actually preconditions, and thus |
| should be specified as "Requires".</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>In 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> Para 12 Change:</p> |
| <blockquote> |
| <p>Required behavior: accept a value of ptr that is null or that was |
| returned by an earlier call ...</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Requires: the value of ptr is null or the value returned by an |
| earlier call ...</p> |
| </blockquote> |
| |
| <p>In 18.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete.array"> [lib.new.delete.array]</a> Para 11 Change:</p> |
| <blockquote> |
| <p>Required behavior: accept a value of ptr that is null or that was |
| returned by an earlier call ...</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Requires: the value of ptr is null or the value returned by an |
| earlier call ...</p> |
| </blockquote> |
| |
| <hr> |
| <a name="320"><h3>320. list::assign overspecified</h3></a><p><b>Section:</b> 23.2.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.deque.cons"> [lib.deque.cons]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 17 May 2001</p> |
| <p> |
| Section 23.2.2.1, paragraphs 6-8 specify that list assign (both forms) have |
| the "effects" of a call to erase followed by a call to insert. |
| </p> |
| |
| <p> |
| I would like to document that implementers have the freedom to implement |
| assign by other methods, as long as the end result is the same and the |
| exception guarantee is as good or better than the basic guarantee. |
| </p> |
| |
| <p> |
| The motivation for this is to use T's assignment operator to recycle |
| existing nodes in the list instead of erasing them and reallocating |
| them with new values. It is also worth noting that, with careful |
| coding, most common cases of assign (everything but assignment with |
| true input iterators) can elevate the exception safety to strong if |
| T's assignment has a nothrow guarantee (with no extra memory cost). |
| Metrowerks does this. However I do not propose that this subtlety be |
| standardized. It is a QoI issue. </p> |
| |
| <p>Existing practise: |
| Metrowerks and SGI recycle nodes, Dinkumware and Rogue Wave don't. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 23.2.2.1/7 from:</p> |
| |
| <blockquote> |
| <p>Effects:</p> |
| |
| <pre> erase(begin(), end()); |
| insert(begin(), first, last); |
| </pre> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Effects: Replaces the contents of the list with the range [first, last).</p> |
| </blockquote> |
| |
| <p>In 23.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.sequence.reqmts"> [lib.sequence.reqmts]</a>, in Table 67 (sequence requirements), |
| add two new rows:</p> |
| <pre> a.assign(i,j) void pre: i,j are not iterators into a. |
| Replaces elements in a with a copy |
| of [i, j). |
| |
| a.assign(n,t) void pre: t is not a reference into a. |
| Replaces elements in a with n copies |
| of t. |
| </pre> |
| |
| <p>Change 23.2.2.1/8 from:</p> |
| |
| <blockquote> |
| <p>Effects:</p> |
| <pre> erase(begin(), end()); |
| insert(begin(), n, t); |
| </pre> |
| </blockquote> |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Effects: Replaces the contents of the list with n copies of t.</p> |
| </blockquote> |
| |
| <p><i>[Redmond: Proposed resolution was changed slightly. Previous |
| version made explicit statement about exception safety, which wasn't |
| consistent with the way exception safety is expressed elsewhere. |
| Also, the change in the sequence requirements is new. Without that |
| change, the proposed resolution would have required that assignment of |
| a subrange would have to work. That too would have been |
| overspecification; it would effectively mandate that assignment use a |
| temporary. Howard provided wording. |
| ]</i></p> |
| |
| <p><i>[Curaçao: Made editorial improvement in wording; changed |
| "Replaces elements in a with copies of elements in [i, j)." |
| with "Replaces the elements of a with a copy of [i, j)." |
| Changes not deemed serious enough to requre rereview.]</i></p> |
| |
| <hr> |
| <a name="321"><h3>321. Typo in num_get</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#WP">WP</a> <b>Submitter:</b> Kevin Djang <b>Date:</b> 17 May 2001</p> |
| <p> |
| Section 22.2.2.1.2 at p7 states that "A length specifier is added to |
| the conversion function, if needed, as indicated in Table 56." |
| However, Table 56 uses the term "length modifier", not "length |
| specifier". |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 22.2.2.1.2 at p7, change the text "A length specifier is added ..." |
| to be "A length modifier is added ..." |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>C uses the term "length modifier". We should be consistent.</p> |
| <hr> |
| <a name="322"><h3>322. iterator and const_iterator should have the same value type</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#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 17 May 2001</p> |
| <p> |
| It's widely assumed that, if X is a container, |
| iterator_traits<X::iterator>::value_type and |
| iterator_traits<X::const_iterator>::value_type should both be |
| X::value_type. However, this is nowhere stated. The language in |
| Table 65 is not precise about the iterators' value types (it predates |
| iterator_traits), and could even be interpreted as saying that |
| iterator_traits<X::const_iterator>::value_type should be "const |
| X::value_type". |
| </p> |
| |
| <p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#279">279</a>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In Table 65 ("Container Requirements"), change the return type for |
| X::iterator to "iterator type whose value type is T". Change the |
| return type for X::const_iterator to "constant iterator type whose |
| value type is T".</p> |
| <p><b>Rationale:</b></p> |
| <p> |
| This belongs as a container requirement, rather than an iterator |
| requirement, because the whole notion of iterator/const_iterator |
| pairs is specific to containers' iterator. |
| </p> |
| <p> |
| It is existing practice that (for example) |
| iterator_traits<list<int>::const_iterator>::value_type |
| is "int", rather than "const int". This is consistent with |
| the way that const pointers are handled: the standard already |
| requires that iterator_traits<const int*>::value_type is int. |
| </p> |
| <hr> |
| <a name="324"><h3>324. Do output iterators have value types?</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#WP">WP</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 7 June 2001</p> |
| |
| <p>Table 73 suggests that output iterators have value types. It |
| requires the expression "*a = t". Additionally, although Table 73 |
| never lists "a = t" or "X(a) = t" in the "expressions" column, it |
| contains a note saying that "a = t" and "X(a) = t" have equivalent |
| (but nowhere specified!) semantics.</p> |
| |
| <p>According to 24.1/9, t is supposed to be "a value of value type |
| T":</p> |
| |
| <blockquote> |
| In the following sections, a and b denote values of X, n denotes a |
| value of the difference type Distance, u, tmp, and m denote |
| identifiers, r denotes a value of X&, t denotes a value of |
| value type T. |
| </blockquote> |
| |
| <p>Two other parts of the standard that are relevant to whether |
| output iterators have value types:</p> |
| |
| <ul> |
| <li>24.1/1 says "All iterators i support the expression *i, |
| resulting in a value of some class, enumeration, or built-in type |
| T, called the value type of the iterator".</li> |
| |
| <li> |
| 24.3.1/1, which says "In the case of an output iterator, the types |
| iterator_traits<Iterator>::difference_type |
| iterator_traits<Iterator>::value_type are both defined as void." |
| </li> |
| </ul> |
| |
| <p>The first of these passages suggests that "*i" is supposed to |
| return a useful value, which contradicts the note in 24.1.2/2 saying |
| that the only valid use of "*i" for output iterators is in an |
| expression of the form "*i = t". The second of these passages appears |
| to contradict Table 73, because it suggests that "*i"'s return value |
| should be void. The second passage is also broken in the case of a an |
| iterator type, like non-const pointers, that satisfies both the output |
| iterator requirements and the forward iterator requirements.</p> |
| |
| <p>What should the standard say about <tt>*i</tt>'s return value when |
| i is an output iterator, and what should it say about that t is in the |
| expression "*i = t"? Finally, should the standard say anything about |
| output iterators' pointer and reference types?</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>24.1 p1, change</p> |
| |
| <blockquote> |
| <p>All iterators <tt>i</tt> support the expression <tt>*i</tt>, resulting |
| in a value of some class, enumeration, or built-in type <tt>T</tt>, |
| called the value type of the iterator.</p> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <p>All input iterators <tt>i</tt> support the expression <tt>*i</tt>, |
| resulting in a value of some class, enumeration, or built-in type |
| <tt>T</tt>, called the value type of the iterator. All output |
| iterators support the expression <tt>*i = o</tt> where <tt>o</tt> is a |
| value of some type that is in the set of types that are <i>writable</i> to |
| the particular iterator type of <tt>i</tt>. |
| </p> |
| </blockquote> |
| |
| <p>24.1 p9, add</p> |
| |
| <blockquote> |
| <p><tt>o</tt> denotes a value of some type that is writable to the |
| output iterator. |
| </p> |
| </blockquote> |
| |
| <p>Table 73, change</p> |
| |
| <blockquote> |
| <pre>*a = t |
| </pre> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <pre>*r = o |
| </pre> |
| </blockquote> |
| |
| <p>and change</p> |
| |
| <blockquote> |
| <pre>*r++ = t |
| </pre> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <pre>*r++ = o |
| </pre> |
| </blockquote> |
| |
| <p><i>[post-Redmond: Jeremy provided wording]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered two options: change all of the language that |
| seems to imply that output iterators have value types, thus making it |
| clear that output iterators have no value types, or else define value |
| types for output iterator consistently. The LWG chose the former |
| option, because it seems clear that output iterators were never |
| intended to have value types. This was a deliberate design decision, |
| and any language suggesting otherwise is simply a mistake.</p> |
| |
| <p>A future revision of the standard may wish to revisit this design |
| decision.</p> |
| <hr> |
| <a name="325"><h3>325. Misleading text in moneypunct<>::do_grouping</h3></a><p><b>Section:</b> 22.2.6.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.moneypunct.virtuals"> [lib.locale.moneypunct.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 02 Jul 2001</p> |
| <p>The Returns clause in 22.2.6.3.2, p3 says about |
| moneypunct<charT>::do_grouping() |
| </p> |
| |
| <blockquote> |
| Returns: A pattern defined identically as the result of |
| numpunct<charT>::do_grouping().241) |
| </blockquote> |
| |
| <p>Footnote 241 then reads</p> |
| |
| <blockquote> |
| This is most commonly the value "\003" (not "3"). |
| </blockquote> |
| |
| <p> |
| The returns clause seems to imply that the two member functions must |
| return an identical value which in reality may or may not be true, |
| since the facets are usually implemented in terms of struct std::lconv |
| and return the value of the grouping and mon_grouping, respectively. |
| The footnote also implies that the member function of the moneypunct |
| facet (rather than the overridden virtual functions in moneypunct_byname) |
| most commonly return "\003", which contradicts the C standard which |
| specifies the value of "" for the (most common) C locale. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the text in Returns clause in 22.2.6.3.2, p3 with the following:</p> |
| |
| <blockquote> |
| Returns: A pattern defined identically as, but not necessarily |
| equal to, the result of numpunct<charT>::do_grouping().241) |
| </blockquote> |
| |
| <p>and replace the text in Footnote 241 with the following:</p> |
| |
| <blockquote> |
| To specify grouping by 3s the value is "\003", not "3". |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p> |
| The fundamental problem is that the description of the locale facet |
| virtuals serves two purposes: describing the behavior of the base |
| class, and describing the meaning of and constraints on the behavior |
| in arbitrary derived classes. The new wording makes that separation a |
| little bit clearer. The footnote (which is nonnormative) is not |
| supposed to say what the grouping is in the "C" locale or in any other |
| locale. It is just a reminder that the values are interpreted as small |
| integers, not ASCII characters. |
| </p> |
| <hr> |
| <a name="327"><h3>327. Typo in time_get facet in table 52</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#WP">WP</a> <b>Submitter:</b> Tiki Wan <b>Date:</b> 06 Jul 2001</p> |
| <p>The <tt>wchar_t</tt> versions of <tt>time_get</tt> and |
| <tt>time_get_byname</tt> are listed incorrectly in table 52, |
| required instantiations. In both cases the second template |
| parameter is given as OutputIterator. It should instead be |
| InputIterator, since these are input facets.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In table 52, required instantiations, in |
| 22.1.1.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.category"> [lib.locale.category]</a>, change</p> |
| <pre> time_get<wchar_t, OutputIterator> |
| time_get_byname<wchar_t, OutputIterator> |
| </pre> |
| <p>to</p> |
| <pre> time_get<wchar_t, InputIterator> |
| time_get_byname<wchar_t, InputIterator> |
| </pre> |
| |
| <p><i>[Redmond: Very minor change in proposed resolution. Original had |
| a typo, wchart instead of wchar_t.]</i></p> |
| |
| <hr> |
| <a name="328"><h3>328. Bad sprintf format modifier in money_put<>::do_put()</h3></a><p><b>Section:</b> 22.2.6.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.money.put.virtuals"> [lib.locale.money.put.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 07 Jul 2001</p> |
| <p>The sprintf format string , "%.01f" (that's the digit one), in the |
| description of the do_put() member functions of the money_put facet in |
| 22.2.6.2.2, p1 is incorrect. First, the f format specifier is wrong |
| for values of type long double, and second, the precision of 01 |
| doesn't seem to make sense. What was most likely intended was |
| "%.0Lf"., that is a precision of zero followed by the L length |
| modifier.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the format string to "%.0Lf".</p> |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious typo</p> |
| <hr> |
| <a name="329"><h3>329. vector capacity, reserve and reallocation</h3></a><p><b>Section:</b> 23.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.priority.queue"> [lib.priority.queue]</a>, 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.stack"> [lib.stack]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Anthony Williams <b>Date:</b> 13 Jul 2001</p> |
| <p> |
| There is an apparent contradiction about which circumstances can cause |
| a reallocation of a vector in Section 23.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.priority.queue"> [lib.priority.queue]</a> and |
| section 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.stack"> [lib.stack]</a>. |
| </p> |
| |
| <p>23.2.4.2p5 says:</p> |
| <blockquote> |
| Notes: Reallocation invalidates all the references, pointers, and iterators |
| referring to the elements in the sequence. It is guaranteed that no |
| reallocation takes place during insertions that happen after a call to |
| reserve() until the time when an insertion would make the size of the vector |
| greater than the size specified in the most recent call to reserve(). |
| </blockquote> |
| |
| <p>Which implies if I do</p> |
| |
| <pre> std::vector<int> vec; |
| vec.reserve(23); |
| vec.reserve(0); |
| vec.insert(vec.end(),1); |
| </pre> |
| |
| <p>then the implementation may reallocate the vector for the insert, |
| as the size specified in the previous call to reserve was zero.</p> |
| |
| <p>However, the previous paragraphs (23.2.4.2, p1-2) state:</p> |
| <blockquote> |
| <p> |
| (capacity) Returns: The total number of elements the vector |
| can hold without requiring reallocation |
| </p> |
| <p> |
| ...After reserve(), capacity() is greater or equal to the |
| argument of reserve if reallocation happens; and equal to the previous value |
| of capacity() otherwise... |
| </p> |
| </blockquote> |
| |
| <p> |
| This implies that vec.capacity() is still 23, and so the insert() |
| should not require a reallocation, as vec.size() is 0. This is backed |
| up by 23.2.4.3p1: |
| </p> |
| <blockquote> |
| (insert) Notes: Causes reallocation if the new size is greater than the old |
| capacity. |
| </blockquote> |
| |
| <p> |
| Though this doesn't rule out reallocation if the new size is less |
| than the old capacity, I think the intent is clear. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the wording of 23.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.priority.queue"> [lib.priority.queue]</a> paragraph 5 to:</p> |
| |
| <blockquote> |
| Notes: Reallocation invalidates all the references, pointers, and |
| iterators referring to the elements in the sequence. It is guaranteed |
| that no reallocation takes place during insertions that happen after a |
| call to reserve() until the time when an insertion would make the size |
| of the vector greater than the value of capacity(). |
| </blockquote> |
| |
| <p><i>[Redmond: original proposed resolution was modified slightly. In |
| the original, the guarantee was that there would be no reallocation |
| until the size would be greater than the value of capacity() after the |
| most recent call to reserve(). The LWG did not believe that the |
| "after the most recent call to reserve()" added any useful |
| information.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>There was general agreement that, when reserve() is called twice in |
| succession and the argument to the second invocation is smaller than |
| the argument to the first, the intent was for the second invocation to |
| have no effect. Wording implying that such cases have an effect on |
| reallocation guarantees was inadvertant.</p> |
| <hr> |
| <a name="331"><h3>331. bad declaration of destructor for ios_base::failure</h3></a><p><b>Section:</b> 27.4.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios::failure"> [lib.ios::failure]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> PremAnand M. Rao <b>Date:</b> 23 Aug 2001</p> |
| <p> |
| With the change in 17.4.4.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.res.on.exception.handling"> [lib.res.on.exception.handling]</a> to state |
| "An implementation may strengthen the exception-specification for a |
| non-virtual function by removing listed exceptions." |
| (issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#119">119</a>) |
| and the following declaration of ~failure() in ios_base::failure |
| </p> |
| <pre> namespace std { |
| class ios_base::failure : public exception { |
| public: |
| ... |
| virtual ~failure(); |
| ... |
| }; |
| } |
| </pre> |
| <p>the class failure cannot be implemented since in 18.6.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.type.info"> [lib.type.info]</a> the destructor of class exception has an empty |
| exception specification:</p> |
| <pre> namespace std { |
| class exception { |
| public: |
| ... |
| virtual ~exception() throw(); |
| ... |
| }; |
| } |
| </pre> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the declaration of ~failure().</p> |
| <p><b>Rationale:</b></p> |
| <p>The proposed resolution is consistent with the way that destructors |
| of other classes derived from <tt>exception</tt> are handled.</p> |
| <hr> |
| <a name="333"><h3>333. does endl imply synchronization with the device?</h3></a><p><b>Section:</b> 27.6.2.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.manip"> [lib.ostream.manip]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> PremAnand M. Rao <b>Date:</b> 27 Aug 2001</p> |
| <p>A footnote in 27.6.2.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.manip"> [lib.ostream.manip]</a> states:</p> |
| <blockquote> |
| [Footnote: The effect of executing cout << endl is to insert a |
| newline character in the output sequence controlled by cout, then |
| synchronize it with any external file with which it might be |
| associated. --- end foonote] |
| </blockquote> |
| |
| <p> |
| Does the term "file" here refer to the external device? |
| This leads to some implementation ambiguity on systems with fully |
| buffered files where a newline does not cause a flush to the device. |
| </p> |
| |
| <p> |
| Choosing to sync with the device leads to significant performance |
| penalties for each call to endl, while not sync-ing leads to |
| errors under special circumstances. |
| </p> |
| |
| <p> |
| I could not find any other statement that explicitly defined |
| the behavior one way or the other. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove footnote 300 from section 27.6.2.7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.manip"> [lib.ostream.manip]</a>.</p> |
| <p><b>Rationale:</b></p> |
| <p>We already have normative text saying what <tt>endl</tt> does: it |
| inserts a newline character and calls <tt>flush</tt>. This footnote |
| is at best redundant, at worst (as this issue says) misleading, |
| because it appears to make promises about what <tt>flush</tt> |
| does.</p> |
| <hr> |
| <a name="334"><h3>334. map::operator[] specification forces inefficient implementation</h3></a><p><b>Section:</b> 23.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map.access"> [lib.map.access]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andrea Griffini <b>Date:</b> 02 Sep 2001</p> |
| <p> |
| The current standard describes map::operator[] using a |
| code example. That code example is however quite |
| inefficient because it requires several useless copies |
| of both the passed key_type value and of default |
| constructed mapped_type instances. |
| My opinion is that was not meant by the comitee to |
| require all those temporary copies. |
| </p> |
| |
| <p>Currently map::operator[] behaviour is specified as: </p> |
| <pre> Returns: |
| (*((insert(make_pair(x, T()))).first)).second. |
| </pre> |
| |
| <p> |
| This specification however uses make_pair that is a |
| template function of which parameters in this case |
| will be deduced being of type const key_type& and |
| const T&. This will create a pair<key_type,T> that |
| isn't the correct type expected by map::insert so |
| another copy will be required using the template |
| conversion constructor available in pair to build |
| the required pair<const key_type,T> instance. |
| </p> |
| |
| <p>If we consider calling of key_type copy constructor |
| and mapped_type default constructor and copy |
| constructor as observable behaviour (as I think we |
| should) then the standard is in this place requiring |
| two copies of a key_type element plus a default |
| construction and two copy construction of a mapped_type |
| (supposing the addressed element is already present |
| in the map; otherwise at least another copy |
| construction for each type). |
| </p> |
| |
| <p>A simple (half) solution would be replacing the description with:</p> |
| <pre> Returns: |
| (*((insert(value_type(x, T()))).first)).second. |
| </pre> |
| |
| <p>This will remove the wrong typed pair construction that |
| requires one extra copy of both key and value.</p> |
| |
| <p>However still the using of map::insert requires temporary |
| objects while the operation, from a logical point of view, |
| doesn't require any. </p> |
| |
| <p>I think that a better solution would be leaving free an |
| implementer to use a different approach than map::insert |
| that, because of its interface, forces default constructed |
| temporaries and copies in this case. |
| The best solution in my opinion would be just requiring |
| map::operator[] to return a reference to the mapped_type |
| part of the contained element creating a default element |
| with the specified key if no such an element is already |
| present in the container. Also a logarithmic complexity |
| requirement should be specified for the operation. |
| </p> |
| |
| <p> |
| This would allow library implementers to write alternative |
| implementations not using map::insert and reaching optimal |
| performance in both cases of the addressed element being |
| present or absent from the map (no temporaries at all and |
| just the creation of a new pair inside the container if |
| the element isn't present). |
| Some implementer has already taken this option but I think |
| that the current wording of the standard rules that as |
| non-conforming. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Replace 23.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map.access"> [lib.map.access]</a> paragraph 1 with |
| </p> |
| <blockquote> |
| <p> |
| -1- Effects: If there is no key equivalent to x in the map, inserts |
| value_type(x, T()) into the map. |
| </p> |
| <p> |
| -2- Returns: A reference to the mapped_type corresponding to x in *this. |
| </p> |
| <p> |
| -3- Complexity: logarithmic. |
| </p> |
| </blockquote> |
| |
| <p><i>[This is the second option mentioned above. Howard provided |
| wording. We may also wish to have a blanket statement somewhere in |
| clause 17 saying that we do not intend the semantics of sample code |
| fragments to be interpreted as specifing exactly how many copies are |
| made. See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#98">98</a> for a similar problem.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This is the second solution described above; as noted, it is |
| consistent with existing practice. |
| </p> |
| |
| <p>Note that we now need to specify the complexity explicitly, because |
| we are no longer defining <tt>operator[]</tt> in terms of |
| <tt>insert</tt>.</p> |
| <hr> |
| <a name="335"><h3>335. minor issue with char_traits, table 37</h3></a><p><b>Section:</b> 21.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits.require"> [lib.char.traits.require]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 06 Sep 2001</p> |
| <p> |
| Table 37, in 21.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits.require"> [lib.char.traits.require]</a>, descibes char_traits::assign |
| as: |
| </p> |
| <pre> X::assign(c,d) assigns c = d. |
| </pre> |
| |
| <p>And para 1 says:</p> |
| |
| <blockquote> |
| [...] c and d denote values of type CharT [...] |
| </blockquote> |
| |
| <p> |
| Naturally, if c and d are <i>values</i>, then the assignment is |
| (effectively) meaningless. It's clearly intended that (in the case of |
| assign, at least), 'c' is intended to be a reference type. |
| </p> |
| |
| <p>I did a quick survey of the four implementations I happened to have |
| lying around, and sure enough they all have signatures:</p> |
| <pre> assign( charT&, const charT& ); |
| </pre> |
| |
| <p>(or the equivalent). It's also described this way in Nico's book. |
| (Not to mention the synopses of char_traits<char> in 21.1.3.1 |
| and char_traits<wchar_t> in 21.1.3.2...) |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following to 21.1.1 para 1:</p> |
| <blockquote> |
| r denotes an lvalue of CharT |
| </blockquote> |
| |
| <p>and change the description of assign in the table to:</p> |
| <pre> X::assign(r,d) assigns r = d |
| </pre> |
| <hr> |
| <a name="336"><h3>336. Clause 17 lack of references to deprecated headers</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#WP">WP</a> <b>Submitter:</b> Detlef Vollmann <b>Date:</b> 05 Sep 2001</p> |
| <p>From c++std-edit-873:</p> |
| |
| <p>17.4.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.headers"> [lib.headers]</a>, Table 11. In this table, the header |
| <strstream> is missing.</p> |
| |
| <p>This shows a general problem: The whole clause 17 refers quite |
| often to clauses 18 through 27, but D.7 is also a part of the standard |
| library (though a deprecated one).</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>To 17.4.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.headers"> [lib.headers]</a> Table 11, C++ Library Headers, add |
| "<strstream>".</p> |
| |
| <p>In the following places, change "clauses 17 through 27" to "clauses |
| 17 through 27 and Annex D":</p> |
| |
| <ul> |
| <li>1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/intro.html#intro.refs"> [intro.refs]</a> Normative references/1/footnote 1</li> |
| <li>1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/intro.html#intro.defs"> [intro.defs]</a> Definitions/1</li> |
| <li>7 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/dcl.html#dcl.dcl"> [dcl.dcl]</a> Library introduction/9</li> |
| <li>17.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.description"> [lib.description]</a> Method of description (Informative)/1</li> |
| <li>17.3.2.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.character.seq"> [lib.character.seq]</a> Character sequences/1/bullet 2</li> |
| <li>17.3.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.functions.within.classes"> [lib.functions.within.classes]</a> Functions within classes/1</li> |
| <li>17.3.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.objects.within.classes"> [lib.objects.within.classes]</a> Private members/1/(2 places)</li> |
| <li>17.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.requirements"> [lib.requirements]</a> Library-wide requirements/1</li> |
| <li>17.4.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.headers"> [lib.headers]</a> Headers/4</li> |
| <li>17.4.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.replacement.functions"> [lib.replacement.functions]</a> Replacement functions/1</li> |
| <li>17.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.global.functions"> [lib.global.functions]</a> Global or non-member functions/2</li> |
| <li>17.4.4.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.protection.within.classes"> [lib.protection.within.classes]</a> Protection within classes/1</li> |
| </ul> |
| |
| |
| <hr> |
| <a name="337"><h3>337. replace_copy_if's template parameter should be InputIterator</h3></a><p><b>Section:</b> 25.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Detlef Vollmann <b>Date:</b> 07 Sep 2001</p> |
| <p>From c++std-edit-876:</p> |
| |
| <p> |
| In section 25.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a> before p4: The name of the first |
| parameter of template replace_copy_if should be "InputIterator" |
| instead of "Iterator". According to 17.3.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.type.descriptions"> [lib.type.descriptions]</a> p1 the |
| parameter name conveys real normative meaning. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change <tt>Iterator</tt> to <tt>InputIterator</tt>.</p> |
| <hr> |
| <a name="338"><h3>338. is whitespace allowed between `-' and a digit?</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 17 Sep 2001</p> |
| <p> |
| From Stage 2 processing in 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>, p8 and 9 (the |
| original text or the text corrected by the proposed resolution of |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#221">221</a>) it seems clear that no whitespace is allowed |
| within a number, but 22.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.numpunct"> [lib.locale.numpunct]</a>, p2, which gives the |
| format for integer and floating point values, says that whitespace is |
| optional between a plusminus and a sign. |
| </p> |
| |
| <p> |
| The text needs to be clarified to either consistently allow or |
| disallow whitespace between a plusminus and a sign. It might be |
| worthwhile to consider the fact that the C library stdio facility does |
| not permit whitespace embedded in numbers and neither does the C or |
| C++ core language (the syntax of integer-literals is given in 2.13.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lex.html#lex.icon"> [lex.icon]</a>, that of floating-point-literals in 2.13.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lex.html#lex.fcon"> [lex.fcon]</a> of the C++ standard). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the first part of 22.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.numpunct"> [lib.locale.numpunct]</a> paragraph 2 from:</p> |
| <blockquote> |
| <p> |
| The syntax for number formats is as follows, where <tt>digit</tt> |
| represents the radix set specified by the <tt>fmtflags</tt> argument |
| value, <tt>whitespace</tt> is as determined by the facet |
| <tt>ctype<charT></tt> (22.2.1.1), and <tt>thousands-sep</tt> and |
| <tt>decimal-point</tt> are the results of corresponding |
| <tt>numpunct<charT></tt> members. Integer values have the |
| format: |
| </p> |
| <pre> integer ::= [sign] units |
| sign ::= plusminus [whitespace] |
| plusminus ::= '+' | '-' |
| units ::= digits [thousands-sep units] |
| digits ::= digit [digits] |
| </pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p> |
| The syntax for number formats is as follows, where <tt>digit</tt> |
| represents the radix set specified by the <tt>fmtflags</tt> argument |
| value, and <tt>thousands-sep</tt> and <tt>decimal-point</tt> are the |
| results of corresponding <tt>numpunct<charT></tt> members. |
| Integer values have the format: |
| </p> |
| <pre> integer ::= [sign] units |
| sign ::= plusminus |
| plusminus ::= '+' | '-' |
| units ::= digits [thousands-sep units] |
| digits ::= digit [digits] |
| </pre> |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>It's not clear whether the format described in 22.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.numpunct"> [lib.locale.numpunct]</a> paragraph 2 has any normative weight: nothing in the |
| standard says how, or whether, it's used. However, there's no reason |
| for it to differ gratuitously from the very specific description of |
| numeric processing in 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>. The proposed |
| resolution removes all mention of "whitespace" from that format.</p> |
| <hr> |
| <a name="339"><h3>339. definition of bitmask type restricted to clause 27</h3></a><p><b>Section:</b> 22.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.category.ctype"> [lib.category.ctype]</a>, 17.3.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 17 September 2001</p> |
| <p> |
| The ctype_category::mask type is declared to be an enum in 22.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.category.ctype"> [lib.category.ctype]</a> with p1 then stating that it is a bitmask type, most |
| likely referring to the definition of bitmask type in 17.3.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a>, p1. However, the said definition only applies to |
| clause 27, making the reference in 22.2.1 somewhat dubious. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Clarify 17.3.2.1.2, p1 by changing the current text from</p> |
| <blockquote> |
| Several types defined in clause 27 are bitmask types. Each bitmask type |
| can be implemented as an enumerated type that overloads certain operators, |
| as an integer type, or as a bitset (23.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.template.bitset"> [lib.template.bitset]</a>). |
| </blockquote> |
| <p>to read</p> |
| <blockquote> |
| Several types defined in clauses lib.language.support through |
| lib.input.output and Annex D are bitmask types. Each bitmask type can |
| be implemented as an enumerated type that overloads certain operators, |
| as an integer type, or as a bitset (lib.template.bitset). |
| </blockquote> |
| |
| <p> |
| Additionally, change the definition in 22.2.1 to adopt the same |
| convention as in clause 27 by replacing the existing text with the |
| following (note, in particluar, the cross-reference to 17.3.2.1.2 in |
| 22.2.1, p1): |
| </p> |
| |
| <blockquote> |
| <p>22.2.1 The ctype category [lib.category.ctype]</p> |
| <pre>namespace std { |
| class ctype_base { |
| public: |
| typedef <b><i>T</i></b> mask; |
| |
| // numeric values are for exposition only. |
| static const mask space = 1 << 0; |
| static const mask print = 1 << 1; |
| static const mask cntrl = 1 << 2; |
| static const mask upper = 1 << 3; |
| static const mask lower = 1 << 4; |
| static const mask alpha = 1 << 5; |
| static const mask digit = 1 << 6; |
| static const mask punct = 1 << 7; |
| static const mask xdigit = 1 << 8; |
| static const mask alnum = alpha | digit; |
| static const mask graph = alnum | punct; |
| }; |
| } |
| </pre> |
| |
| <p>The type <tt>mask</tt> is a bitmask type (17.3.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a>).</p> |
| </blockquote> |
| |
| <p><i>[Curaçao: The LWG notes that T above should be bold-italics to be |
| consistent with the rest of the standard.]</i></p> |
| |
| <hr> |
| <a name="340"><h3>340. interpretation of <tt>has_facet<Facet>(loc)</tt> |
| </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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2001</p> |
| <p> |
| It's unclear whether 22.1.1.1.1, p3 says that |
| <tt>has_facet<Facet>(loc)</tt> returns true for any <tt>Facet</tt> |
| from Table 51 or whether it includes Table 52 as well: |
| </p> |
| |
| <blockquote> |
| For any locale <tt>loc</tt> either constructed, or returned by |
| locale::classic(), and any facet <tt>Facet</tt> that is a member of a |
| standard category, <tt>has_facet<Facet>(loc)</tt> is true. Each |
| locale member function which takes a <tt>locale::category</tt> |
| argument operates on the corresponding set of facets. |
| </blockquote> |
| |
| <p> |
| It seems that it comes down to which facets are considered to be members of a |
| standard category. Intuitively, I would classify all the facets in Table 52 as |
| members of their respective standard categories, but there are an unbounded set |
| of them... |
| </p> |
| |
| <p> |
| The paragraph implies that, for instance, <tt>has_facet<num_put<C, |
| OutputIterator> >(loc)</tt> must always return true. I don't think that's |
| possible. If it were, then <tt>use_facet<num_put<C, OutputIterator> |
| >(loc)</tt> would have to return a reference to a distinct object for each |
| valid specialization of <tt>num_put<C, OutputIteratory></tt>, which is |
| clearly impossible. |
| </p> |
| |
| <p> |
| On the other hand, if none of the facets in Table 52 is a member of a standard |
| category then none of the locale member functions that operate on entire |
| categories of facets will work properly. |
| </p> |
| |
| <p> |
| It seems that what p3 should mention that it's required (permitted?) |
| to hold only for specializations of <tt>Facet</tt> from Table 52 on |
| <tt>C</tt> from the set { <tt>char</tt>, <tt>wchar_t</tt> }, and |
| <tt>InputIterator</tt> and <tt>OutputIterator</tt> from the set of |
| { |
| {i,o}<tt>streambuf_iterator</tt><{<tt>char</tt>,<tt>wchar_t</tt>}<tt>></tt> |
| }. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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>, paragraph 3, change |
| "that is a member of a standard category" to "shown in Table 51".</p> |
| <p><b>Rationale:</b></p> |
| <p>The facets in Table 52 are an unbounded set. Locales should not be |
| required to contain an infinite number of facets.</p> |
| |
| <p>It's not necessary to talk about which values of InputIterator and |
| OutputIterator must be supported. Table 51 already contains a |
| complete list of the ones we need.</p> |
| <hr> |
| <a name="341"><h3>341. Vector reallocation and swap</h3></a><p><b>Section:</b> 23.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.priority.queue"> [lib.priority.queue]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Anthony Williams <b>Date:</b> 27 Sep 2001</p> |
| <p>It is a common idiom to reduce the capacity of a vector by swapping it with |
| an empty one:</p> |
| <pre> std::vector<SomeType> vec; |
| // fill vec with data |
| std::vector<SomeType>().swap(vec); |
| // vec is now empty, with minimal capacity |
| </pre> |
| |
| <p>However, the wording of 23.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.priority.queue"> [lib.priority.queue]</a>paragraph 5 prevents |
| the capacity of a vector being reduced, following a call to |
| reserve(). This invalidates the idiom, as swap() is thus prevented |
| from reducing the capacity. The proposed wording for issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#329">329</a> does not affect this. Consequently, the example above |
| requires the temporary to be expanded to cater for the contents of |
| vec, and the contents be copied across. This is a linear-time |
| operation.</p> |
| |
| <p>However, the container requirements state that swap must have constant |
| complexity (23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> note to table 65).</p> |
| |
| <p>This is an important issue, as reallocation affects the validity of |
| references and iterators.</p> |
| |
| <p>If the wording of 23.2.4.2p5 is taken to be the desired intent, then |
| references and iterators remain valid after a call to swap, if they refer to |
| an element before the new end() of the vector into which they originally |
| pointed, in which case they refer to the element at the same index position. |
| Iterators and references that referred to an element whose index position |
| was beyond the new end of the vector are invalidated.</p> |
| |
| <p>If the note to table 65 is taken as the desired intent, then there are two |
| possibilities with regard to iterators and references:</p> |
| |
| <ol> |
| <li>All Iterators and references into both vectors are invalidated.</li> |
| <li>Iterators and references into either vector remain valid, and remain |
| pointing to the same element. Consequently iterators and references that |
| referred to one vector now refer to the other, and vice-versa.</li> |
| </ol> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a new paragraph after 23.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.priority.queue"> [lib.priority.queue]</a> paragraph 5:</p> |
| <blockquote> |
| <pre> void swap(vector<T,Allocator>& x); |
| </pre> |
| <p><b>Effects:</b> Exchanges the contents and capacity() of <tt>*this</tt> |
| with that of <tt>x</tt>.</p> |
| <p><b>Complexity:</b> Constant time.</p> |
| </blockquote> |
| |
| <p><i>[This solves the problem reported for this issue. We may also |
| have a problem with a circular definition of swap() for other |
| containers.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| swap should be constant time. The clear intent is that it should just |
| do pointer twiddling, and that it should exchange all properties of |
| the two vectors, including their reallocation guarantees. |
| </p> |
| <hr> |
| <a name="345"><h3>345. type tm in <cwchar></h3></a><p><b>Section:</b> 21.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.c.strings"> [lib.c.strings]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Clark Nelson <b>Date:</b> 19 Oct 2001</p> |
| <p> |
| C99, and presumably amendment 1 to C90, specify that <wchar.h> |
| declares struct tm as an incomplete type. However, table 48 in 21.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.c.strings"> [lib.c.strings]</a> does not mention the type tm as being declared in |
| <cwchar>. Is this omission intentional or accidental? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In section 21.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.c.strings"> [lib.c.strings]</a>, add "tm" to table 48.</p> |
| <hr> |
| <a name="346"></a><h3><a name="346">346. Some iterator member functions should be const</a></h3><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#WP">WP</a> <b>Submitter:</b> Jeremy Siek <b>Date:</b> 20 Oct 2001</p> |
| <p>Iterator member functions and operators that do not change the state |
| of the iterator should be defined as const member functions or as |
| functions that take iterators either by const reference or by |
| value. The standard does not explicitly state which functions should |
| be const. Since this a fairly common mistake, the following changes |
| are suggested to make this explicit.</p> |
| |
| <p>The tables almost indicate constness properly through naming: r |
| for non-const and a,b for const iterators. The following changes |
| make this more explicit and also fix a couple problems.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a> Change the first section of p9 from |
| "In the following sections, a and b denote values of X..." to |
| "In the following sections, a and b denote values of type const X...".</p> |
| |
| <p>In Table 73, change</p> |
| <pre> a->m U& ... |
| </pre> |
| |
| <p>to</p> |
| |
| <pre> a->m const U& ... |
| r->m U& ... |
| </pre> |
| |
| <p>In Table 73 expression column, change</p> |
| |
| <pre> *a = t |
| </pre> |
| |
| <p>to</p> |
| |
| <pre> *r = t |
| </pre> |
| |
| <p><i>[Redmond: The container requirements should be reviewed to see if |
| the same problem appears there.]</i></p> |
| |
| <hr> |
| <a name="347"><h3>347. locale::category and bitmask requirements</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#WP">WP</a> <b>Submitter:</b> P.J. Plauger, Nathan Myers <b>Date:</b> 23 Oct 2001</p> |
| <p> |
| In 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> paragraph 1, the category members |
| are described as bitmask elements. In fact, the bitmask requirements |
| in 17.3.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a> don't seem quite right: <tt>none</tt> |
| and <tt>all</tt> are bitmask constants, not bitmask elements.</p> |
| |
| <p>In particular, the requirements for <tt>none</tt> interact poorly |
| with the requirement that the LC_* constants from the C library must |
| be recognizable as C++ locale category constants. LC_* values should |
| not be mixed with these values to make category values.</p> |
| |
| <p>We have two options for the proposed resolution. Informally: |
| option 1 removes the requirement that LC_* values be recognized as |
| category arguments. Option 2 changes the category type so that this |
| requirement is implementable, by allowing <tt>none</tt> to be some |
| value such as 0x1000 instead of 0.</p> |
| |
| <p>Nathan writes: "I believe my proposed resolution [Option 2] merely |
| re-expresses the status quo more clearly, without introducing any |
| changes beyond resolving the DR.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the first two paragraphs of 22.1.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.types"> [lib.locale.types]</a> with:</p> |
| <blockquote> |
| <pre> typedef int category; |
| </pre> |
| |
| <p>Valid category values include the <tt>locale</tt> member bitmask |
| elements <tt>collate</tt>, <tt>ctype</tt>, <tt>monetary</tt>, |
| <tt>numeric</tt>, <tt>time</tt>, and <tt>messages</tt>, each of which |
| represents a single locale category. In addition, <tt>locale</tt> member |
| bitmask constant <tt>none</tt> is defined as zero and represents no |
| category. And locale member bitmask constant <tt>all</tt> is defined such that |
| the expression</p> |
| <pre> (collate | ctype | monetary | numeric | time | messages | all) == all |
| </pre> |
| <p> |
| is <tt>true</tt>, and represents the union of all categories. Further |
| the expression <tt>(X | Y)</tt>, where <tt>X</tt> and <tt>Y</tt> each |
| represent a single category, represents the union of the two |
| categories. |
| </p> |
| |
| <p> |
| <tt>locale</tt> member functions expecting a <tt>category</tt> |
| argument require one of the <tt>category</tt> values defined above, or |
| the union of two or more such values. Such a <tt>category</tt> |
| argument identifies a set of locale categories. Each locale category, |
| in turn, identifies a set of locale facets, including at least those |
| shown in Table 51: |
| </p> |
| </blockquote> |
| <p><i>[Curaçao: need input from locale experts.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| |
| <p>The LWG considered, and rejected, an alternate proposal (described |
| as "Option 2" in the discussion). The main reason for rejecting it |
| was that library implementors were concerened about implementation |
| difficult, given that getting a C++ library to work smoothly with a |
| separately written C library is already a delicate business. Some |
| library implementers were also concerned about the issue of adding |
| extra locale categories.</p> |
| |
| <blockquote> |
| <p><b>Option 2:</b> <br> |
| Replace the first paragraph of 22.1.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.types"> [lib.locale.types]</a> with:</p> |
| <blockquote> |
| <p> |
| Valid category values include the enumerated values. In addition, the |
| result of applying commutative operators | and & to any two valid |
| values is valid, and results in the setwise union and intersection, |
| respectively, of the argument categories. The values <tt>all</tt> and |
| <tt>none</tt> are defined such that for any valid value <tt>cat</tt>, the |
| expressions <tt>(cat | all == all)</tt>, <tt>(cat & all == cat)</tt>, |
| <tt>(cat | none == cat)</tt> and <tt>(cat & none == none)</tt> are |
| true. For non-equal values <tt>cat1</tt> and <tt>cat2</tt> of the |
| remaining enumerated values, <tt>(cat1 & cat2 == none)</tt> is true. |
| For any valid categories <tt>cat1</tt> and <tt>cat2</tt>, the result |
| of <tt>(cat1 & ~cat2)</tt> is valid, and equals the setwise union of |
| those categories found in <tt>cat1</tt> but not found in <tt>cat2</tt>. |
| [Footnote: it is not required that <tt>all</tt> equal the setwise union |
| of the other enumerated values; implementations may add extra categories.] |
| </p> |
| </blockquote> |
| </blockquote> |
| <hr> |
| <a name="349"><h3>349. Minor typographical error in ostream_iterator</h3></a><p><b>Section:</b> 24.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.ostream.iterator"> [lib.ostream.iterator]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 24 Oct 2001</p> |
| <p>24.5.2 [lib.ostream.iterator] states:</p> |
| <pre> [...] |
| |
| private: |
| // basic_ostream<charT,traits>* out_stream; exposition only |
| // const char* delim; exposition only |
| </pre> |
| |
| <p>Whilst it's clearly marked "exposition only", I suspect 'delim' |
| should be of type 'const charT*'.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 24.5.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.ostream.iterator"> [lib.ostream.iterator]</a>, replace <tt>const char* delim</tt> with |
| <tt>const charT* delim</tt>. |
| </p> |
| <hr> |
| <a name="352"><h3>352. missing fpos requirements</h3></a><p><b>Section:</b> 21.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits.typedefs"> [lib.char.traits.typedefs]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 2 Dec 2001</p> |
| <p> |
| <i>(1)</i> |
| There are no requirements on the <tt>stateT</tt> template parameter of |
| <tt>fpos</tt> listed in 27.4.3. The interface appears to require that |
| the type be at least Assignable and CopyConstructible (27.4.3.1, p1), |
| and I think also DefaultConstructible (to implement the operations in |
| Table 88). |
| </p> |
| <p> |
| 21.1.2, p3, however, only requires that |
| <tt>char_traits<charT>::state_type</tt> meet the requirements of |
| CopyConstructible types. |
| </p> |
| <p> |
| <i>(2)</i> |
| Additionally, the <tt>stateT</tt> template argument has no |
| corresponding typedef in fpos which might make it difficult to use in |
| generic code. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Modify 21.1.2, p4 from |
| </p> |
| <p> |
| Requires: <tt>state_type</tt> shall meet the requirements of |
| CopyConstructible types (20.1.3). |
| </p> |
| <p> |
| Requires: state_type shall meet the requirements of Assignable |
| (23.1, p4), CopyConstructible (20.1.3), and |
| DefaultConstructible (20.1.4) types. |
| </p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG feels this is two issues, as indicated above. The first is |
| a defect---std::basic_fstream is unimplementable without these |
| additional requirements---and the proposed resolution fixes it. The |
| second is questionable; who would use that typedef? The class |
| template fpos is used only in a very few places, all of which know the |
| state type already. Unless motivation is provided, the second should |
| be considered NAD.</p> |
| <hr> |
| <a name="354"><h3>354. Associative container lower/upper bound requirements</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#WP">WP</a> <b>Submitter:</b> Hans Aberg <b>Date:</b> 17 Dec 2001</p> |
| <p> |
| Discussions in the thread "Associative container lower/upper bound |
| requirements" on comp.std.c++ suggests that there is a defect in the |
| C++ standard, Table 69 of section 23.1.2, "Associative containers", |
| [lib.associative.reqmts]. It currently says:</p> |
| |
| <blockquote> |
| <p> |
| a.find(k): returns an iterator pointing to an element with the key equivalent to |
| k, or a.end() if such an element is not found. |
| </p> |
| |
| <p> |
| a.lower_bound(k): returns an iterator pointing to the first element with |
| key not less than k. |
| </p> |
| |
| <p> |
| a.upper_bound(k): returns an iterator pointing to the first element with |
| key greater than k. |
| </p> |
| </blockquote> |
| |
| <p> |
| We have "or a.end() if such an element is not found" for |
| <tt>find</tt>, but not for <tt>upper_bound</tt> or |
| <tt>lower_bound</tt>. As the text stands, one would be forced to |
| insert a new element into the container and return an iterator to that |
| in case the sought iterator does not exist, which does not seem to be |
| the intention (and not possible with the "const" versions). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change Table 69 of section 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> indicated entries |
| to:</p> |
| |
| <blockquote> |
| <p> |
| a.lower_bound(k): returns an iterator pointing to the first element with |
| key not less than k, or a.end() if such an element is not found. |
| </p> |
| |
| <p> |
| a.upper_bound(k): returns an iterator pointing to the first element with |
| key greater than k, or a.end() if such an element is not found. |
| </p> |
| </blockquote> |
| |
| <p><i>[Curaçao: LWG reviewed PR.]</i></p> |
| |
| <hr> |
| <a name="355"><h3>355. Operational semantics for a.back()</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#WP">WP</a> <b>Submitter:</b> Yaroslav Mironov <b>Date:</b> 23 Jan 2002</p> |
| |
| <p>Table 68 "Optional Sequence Operations" in 23.1.1/12 |
| specifies operational semantics for "a.back()" as |
| "*--a.end()", which may be ill-formed <i>[because calling |
| operator-- on a temporary (the return) of a built-in type is |
| ill-formed]</i>, provided a.end() returns a simple pointer rvalue |
| (this is almost always the case for std::vector::end(), for |
| example). Thus, the specification is not only incorrect, it |
| demonstrates a dangerous construct: "--a.end()" may |
| successfully compile and run as intended, but after changing the type |
| of the container or the mode of compilation it may produce |
| compile-time error. </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the specification in table 68 "Optional Sequence |
| Operations" in 23.1.1/12 for "a.back()" from</p> |
| |
| |
| <blockquote> |
| *--a.end() |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| { iterator tmp = a.end(); --tmp; return *tmp; } |
| </blockquote> |
| |
| <p>and the specification for "a.pop_back()" from</p> |
| |
| <blockquote> |
| a.erase(--a.end()) |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| { iterator tmp = a.end(); --tmp; a.erase(tmp); } |
| </blockquote> |
| |
| <p><i>[Curaçao: LWG changed PR from "{ X::iterator tmp = |
| a.end(); return *--tmp; }" to "*a.rbegin()", and from |
| "{ X::iterator tmp = a.end(); a.erase(--tmp); }" to |
| "a.erase(rbegin())".]</i></p> |
| |
| <p><i>[There is a second possible defect; table 68 "Optional |
| Sequence Operations" in the "Operational Semantics" |
| column uses operations present only in the "Reversible |
| Container" requirements, yet there is no stated dependency |
| between these separate requirements tables. Ask in Santa Cruz if the |
| LWG would like a new issue opened.]</i></p> |
| |
| <p><i>[Santa Cruz: the proposed resolution is even worse than what's in |
| the current standard: erase is undefined for reverse iterator. If |
| we're going to make the change, we need to define a temporary and |
| use operator--. Additionally, we don't know how prevalent this is: |
| do we need to make this change in more than one place? Martin has |
| volunteered to review the standard and see if this problem occurs |
| elsewhere.]</i></p> |
| |
| <p><i>[Oxford: Matt provided new wording to address the concerns raised |
| in Santa Cruz. It does not appear that this problem appears |
| anywhere else in clauses 23 or 24.]</i></p> |
| |
| <p><i>[Kona: In definition of operational semantics of back(), change |
| "*tmp" to "return *tmp;"]</i></p> |
| |
| <hr> |
| <a name="358"><h3>358. interpreting <tt>thousands_sep</tt> after a <tt>decimal_point</tt> |
| </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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 Mar 2002</p> |
| <p> |
| I don't think <tt>thousands_sep</tt> is being treated correctly after |
| decimal_point has been seen. Since grouping applies only to the |
| integral part of the number, the first such occurrence should, IMO, |
| terminate Stage 2. (If it does not terminate it, then 22.2.2.1.2, p12 |
| and 22.2.3.1.2, p3 need to explain how <tt>thousands_sep</tt> is to be |
| interpreted in the fractional part of a number.) |
| </p> |
| |
| <p> |
| The easiest change I can think of that resolves this issue would be |
| something like below. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the first sentence of 22.2.2.1.2, p9 from |
| </p> |
| |
| <blockquote> |
| If discard is true then the position of the character is |
| remembered, but the character is otherwise ignored. If it is not |
| discarded, then a check is made to determine if c is allowed as |
| the next character of an input field of the conversion specifier |
| returned by stage 1. If so it is accumulated. |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| If <tt>discard</tt> is true, then if <tt>'.'</tt> has not yet been |
| accumulated, then the position of the character is remembered, but |
| the character is otherwise ignored. Otherwise, if <tt>'.'</tt> has |
| already been accumulated, the character is discarded and Stage 2 |
| terminates. ... |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p>We believe this reflects the intent of the Standard. Thousands sep |
| characters after the decimal point are not useful in any locale. |
| Some formatting conventions do group digits that follow the decimal |
| point, but they usually introduce a different grouping character |
| instead of reusing the thousand sep character. If we want to add |
| support for such conventions, we need to do so explicitly.</p> |
| |
| <hr> |
| <a name="359"><h3>359. num_put<>::do_put (..., bool) undocumented</h3></a><p><b>Section:</b> 22.2.2.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.members"> [lib.facet.num.put.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 Mar 2002</p> |
| <p>22.2.2.2.1, p1:</p> |
| |
| <pre> iter_type put (iter_type out, ios_base& str, char_type fill, |
| bool val) const; |
| ... |
| |
| 1 Returns: do_put (out, str, fill, val). |
| </pre> |
| |
| <p>AFAICS, the behavior of do_put (..., bool) is not documented anywhere, |
| however, 22.2.2.2.2, p23:</p> |
| |
| <blockquote> |
| <pre>iter_type put (iter_type out, ios_base& str, char_type fill, |
| bool val) const; |
| </pre> |
| |
| |
| Effects: If (str.flags() & ios_base::boolalpha) == 0 then do |
| out = do_put(out, str, fill, (int)val) |
| Otherwise do |
| <pre> string_type s = |
| val ? use_facet<ctype<charT> >(loc).truename() |
| : use_facet<ctype<charT> >(loc).falsename(); |
| </pre> |
| and then insert the characters of s into out. <i>out</i>. |
| </blockquote> |
| |
| <p> |
| This means that the bool overload of <tt>do_put()</tt> will never be called, |
| which contradicts the first paragraph. Perhaps the declaration |
| should read <tt>do_put()</tt>, and not <tt>put()</tt>? |
| </p> |
| |
| <p> |
| Note also that there is no <b>Returns</b> clause for this function, which |
| should probably be corrected, just as should the second occurrence |
| of <i>"out."</i> in the text. |
| </p> |
| |
| <p> |
| I think the least invasive change to fix it would be something like |
| the following: |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a>, just above paragraph 1, remove |
| the <tt>bool</tt> overload.</p> |
| |
| <p> |
| In 22.2.2.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a>, p23, make the following changes |
| </p> |
| |
| <blockquote> |
| Replace <tt>put()</tt> with <tt>do_put()</tt> in the declaration |
| of the member function. |
| </blockquote> |
| |
| <blockquote> |
| Change the <b>Effects</b> clause to a <b>Returns</b> clause (to |
| avoid the requirement to call <tt>do_put(..., int)</tt> from <tt> |
| do_put (..., bool))</tt> |
| like so: |
| </blockquote> |
| |
| <blockquote> |
| 23 <b>Returns</b>: If <tt>(str.flags() & |
| ios_base::boolalpha) == 0</tt> then |
| <tt>do_put (out, str, fill, (long)val)</tt> |
| Otherwise the function obtains a string <tt>s</tt> as if by |
| <pre> string_type s = |
| val ? use_facet<ctype<charT> >(loc).truename() |
| : use_facet<ctype<charT> >(loc).falsename(); |
| </pre> |
| and then inserts each character <tt>c</tt> of s into out via |
| <tt>*out++ = c</tt> |
| and returns <tt>out</tt>. |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This fixes a couple of obvious typos, and also fixes what appears to |
| be a requirement of gratuitous inefficiency. |
| </p> |
| <hr> |
| <a name="360"><h3>360. locale mandates inefficient implementation</h3></a><p><b>Section:</b> 22.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale"> [lib.locale]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 Mar 2002</p> |
| <p> |
| 22.1.1, p7 (copied below) allows iostream formatters and extractors |
| to make assumptions about the values returned from facet members. |
| However, such assumptions are apparently not guaranteed to hold |
| in other cases (e.g., when the facet members are being called directly |
| rather than as a result of iostream calls, or between successive |
| calls to the same iostream functions with no interevening calls to |
| <tt>imbue()</tt>, or even when the facet member functions are called |
| from other member functions of other facets). This restriction |
| prevents locale from being implemented efficiently. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the first sentence in 22.1.1, p7 from</p> |
| <blockquote> |
| In successive calls to a locale facet member function during |
| a call to an iostream inserter or extractor or a streambuf member |
| function, the returned result shall be identical. [Note: This |
| implies that such results may safely be reused without calling |
| the locale facet member function again, and that member functions |
| of iostream classes cannot safely call <tt>imbue()</tt> |
| themselves, except as specified elsewhere. --end note] |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| In successive calls to a locale facet member function on a facet |
| object installed in the same locale, the returned result shall be |
| identical. ... |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p>This change is reasonable becuase it clarifies the intent of this |
| part of the standard.</p> |
| <hr> |
| <a name="362"><h3>362. bind1st/bind2nd type safety</h3></a><p><b>Section:</b> D.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/future.html#depr.lib.binders"> [depr.lib.binders]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Andrew Demkin <b>Date:</b> 26 Apr 2002</p> |
| <p> |
| The definition of bind1st() (<font color="red">20.5.6.2</font>) can result in |
| the construction of an unsafe binding between incompatible pointer |
| types. For example, given a function whose first parameter type is |
| 'pointer to T', it's possible without error to bind an argument of |
| type 'pointer to U' when U does not derive from T: |
| </p> |
| <pre> foo(T*, int); |
| |
| struct T {}; |
| struct U {}; |
| |
| U u; |
| |
| int* p; |
| int* q; |
| |
| for_each(p, q, bind1st(ptr_fun(foo), &u)); // unsafe binding |
| </pre> |
| |
| <p> |
| The definition of bind1st() includes a functional-style conversion to |
| map its argument to the expected argument type of the bound function |
| (see below): |
| </p> |
| <pre> typename Operation::first_argument_type(x) |
| </pre> |
| |
| <p> |
| A functional-style conversion (5.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/expr.html#expr.type.conv"> [expr.type.conv]</a>) is defined to be |
| semantically equivalent to an explicit cast expression (5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/expr.html#expr.cast"> [expr.cast]</a>), which may (according to 5.4, paragraph 5) be interpreted |
| as a reinterpret_cast, thus masking the error. |
| </p> |
| |
| <p>The problem and proposed change also apply to <font color="red">20.5.6.4</font>.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add this sentence to the end of 20.5.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.arithmetic.operations"> [lib.arithmetic.operations]</a>/1: |
| "Binders <tt>bind1st</tt> and <tt>bind2nd</tt> are deprecated in |
| favor of <tt>std::tr1::bind</tt>."</p> |
| |
| <p>(Notes to editor: (1) when and if tr1::bind is incorporated into |
| the standard, "std::tr1::bind" should be changed to "std::bind". (2) |
| 20.5.6 should probably be moved to Annex D.</p> |
| <p><b>Rationale:</b></p> |
| <p>There is no point in fixing bind1st and bind2nd. tr1::bind is a |
| superior solution. It solves this problem and others.</p> |
| <hr> |
| <a name="363"><h3>363. Missing exception specification in 27.4.2.1.1</h3></a><p><b>Section:</b> 27.4.2.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios::failure"> [lib.ios::failure]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Walter Brown and Marc Paterno <b>Date:</b> 20 May 2002</p> |
| <p> |
| The destructor of ios_base::failure should have an empty throw |
| specification, because the destructor of its base class, exception, is |
| declared in this way. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the destructor to</p> |
| <pre> virtual ~failure() throw(); |
| </pre> |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious glitch. This is almost editorial.</p> |
| <hr> |
| <a name="364"><h3>364. Inconsistent wording in 27.5.2.4.2</h3></a><p><b>Section:</b> 27.5.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Walter Brown, Marc Paterno <b>Date:</b> 10 May 2002</p> |
| <p> |
| 27.5.2.4.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a> paragraph 1 is inconsistent with the Effects |
| clause for seekoff. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Make this paragraph, the Effects clause for setbuf, consistent in wording |
| with the Effects clause for seekoff in paragraph 3 by amending paragraph 1 |
| to indicate the purpose of setbuf: |
| </p> |
| |
| <p>Original text:</p> |
| |
| <blockquote> |
| 1 Effects: Performs an operation that is defined separately for each |
| class derived from basic_streambuf in this clause (27.7.1.3, 27.8.1.4). |
| </blockquote> |
| |
| <p>Proposed text:</p> |
| |
| <blockquote> |
| 1 Effects: Influences stream buffering in a way that is defined separately |
| for each class derived from basic_streambuf in this clause |
| (27.7.1.3, 27.8.1.4). |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG doesn't believe there is any normative difference between |
| the existing wording and what's in the proposed resolution, but the |
| change may make the intent clearer.</p> |
| <hr> |
| <a name="365"><h3>365. Lack of const-qualification in clause 27</h3></a><p><b>Section:</b> 27 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Walter Brown, Marc Paterno <b>Date:</b> 10 May 2002</p> |
| <p> |
| Some stream and streambuf member functions are declared non-const, |
| even thought they appear only to report information rather than to |
| change an object's logical state. They should be declared const. See |
| document N1360 for details and rationale. |
| </p> |
| |
| <p>The list of member functions under discussion: <tt>in_avail</tt>, |
| <tt>showmanyc</tt>, <tt>tellg</tt>, <tt>tellp</tt>, <tt>is_open</tt>.</p> |
| |
| <p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#73">73</a></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.8.1.5, 27.8.1.7, 27.8.1.8, 27.8.1.10, 27.8.1.11, and 27.8.1.13</p> |
| <p>Replace</p> |
| <pre> bool is_open(); |
| </pre> |
| <p>with</p> |
| <pre> bool is_open() const; |
| </pre> |
| <p><b>Rationale:</b></p> |
| <p>Of the changes proposed in N1360, the only one that is safe is |
| changing the filestreams' is_open to const. The LWG believed that |
| this was NAD the first time it considered this issue (issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#73">73</a>), but now thinks otherwise. The corresponding streambuf |
| member function, after all,is already const.</p> |
| |
| <p>The other proposed changes are less safe, because some streambuf |
| functions that appear merely to report a value do actually perform |
| mutating operations. It's not even clear that they should be |
| considered "logically const", because streambuf has two interfaces, a |
| public one and a protected one. These functions may, and often do, |
| change the state as exposed by the protected interface, even if the |
| state exposed by the public interface is unchanged.</p> |
| |
| <p>Note that implementers can make this change in a binary compatible |
| way by providing both overloads; this would be a conforming extension.</p> |
| |
| <hr> |
| <a name="369"><h3>369. io stream objects and static ctors</h3></a><p><b>Section:</b> 27.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.objects"> [lib.iostream.objects]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Ruslan Abdikeev <b>Date:</b> 8 Jul 2002</p> |
| <p> |
| Is it safe to use standard iostream objects from constructors of |
| static objects? Are standard iostream objects constructed and are |
| their associations established at that time? |
| </p> |
| |
| <p>Surpisingly enough, Standard does NOT require that.</p> |
| |
| <p> |
| 27.3/2 [lib.iostream.objects] guarantees that standard iostream |
| objects are constructed and their associations are established before |
| the body of main() begins execution. It also refers to ios_base::Init |
| class as the panacea for constructors of static objects. |
| </p> |
| |
| <p> |
| However, there's nothing in 27.3 [lib.iostream.objects], |
| in 27.4.2 [lib.ios.base], and in 27.4.2.1.6 [lib.ios::Init], |
| that would require implementations to allow access to standard |
| iostream objects from constructors of static objects. |
| </p> |
| |
| <p>Details:</p> |
| |
| <p>Core text refers to some magic object ios_base::Init, which will |
| be discussed below:</p> |
| |
| <blockquote> |
| "The [standard iostream] objects are constructed, and their |
| associations are established at some time prior to or during |
| first time an object of class basic_ios<charT,traits>::Init |
| is constructed, and in any case before the body of main |
| begins execution." (27.3/2 [lib.iostream.objects]) |
| </blockquote> |
| |
| <p> |
| The first <i>non-normative</i> footnote encourages implementations |
| to initialize standard iostream objects earlier than required. |
| </p> |
| |
| <p>However, the second <i>non-normative</i> footnote makes an explicit |
| and unsupported claim:</p> |
| |
| <blockquote> |
| "Constructors and destructors for static objects can access these |
| [standard iostream] objects to read input from stdin or write output |
| to stdout or stderr." (27.3/2 footnote 265 [lib.iostream.objects]) |
| </blockquote> |
| |
| <p> |
| The only bit of magic is related to that ios_base::Init class. AFAIK, |
| the rationale behind ios_base::Init was to bring an instance of this |
| class to each translation unit which #included <iostream> or |
| related header. Such an inclusion would support the claim of footnote |
| quoted above, because in order to use some standard iostream object it |
| is necessary to #include <iostream>. |
| </p> |
| |
| <p> |
| However, while Standard explicitly describes ios_base::Init as |
| an appropriate class for doing the trick, I failed to found a |
| mention of an _instance_ of ios_base::Init in Standard. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add to 27.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostream.objects"> [lib.iostream.objects]</a>, p2, immediately before the last sentence |
| of the paragraph, the following two sentences:</p> |
| |
| <blockquote> |
| If a translation unit includes <iostream>, or explicitly |
| constructs an ios_base::Init object, these stream objects shall |
| be constructed before dynamic initialization of non-local |
| objects defined later in that translation unit, and these stream |
| objects shall be destroyed after the destruction of dynamically |
| initialized non-local objects defined later in that translation unit. |
| </blockquote> |
| |
| <p><i>[Lillehammer: Matt provided wording.]</i></p> |
| <p><i>[Mont Tremblant: Matt provided revised wording.]</i></p> |
| <p><b>Rationale:</b></p> |
| <p> |
| The original proposed resolution unconditionally required |
| implementations to define an ios_base::Init object of some |
| implementation-defined name in the header <iostream>. That's an |
| overspecification. First, defining the object may be unnecessary |
| and even detrimental to performance if an implementation can |
| guarantee that the 8 standard iostream objects will be initialized |
| before any other user-defined object in a program. Second, there |
| is no need to require implementations to document the name of the |
| object.</p> |
| |
| <p> |
| The new proposed resolution gives users guidance on what they need to |
| do to ensure that stream objects are constructed during startup.</p> |
| <hr> |
| <a name="370"><h3>370. Minor error in basic_istream::get</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#WP">WP</a> <b>Submitter:</b> Ray Lischner <b>Date:</b> 15 Jul 2002</p> |
| <p>Defect report for description of basic_istream::get (section 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 15. The description for the get function |
| with the following signature:</p> |
| |
| <pre> basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& |
| sb); |
| </pre> |
| |
| <p>is incorrect. It reads</p> |
| |
| <blockquote> |
| Effects: Calls get(s,n,widen('\n')) |
| </blockquote> |
| |
| <p>which I believe should be:</p> |
| |
| <blockquote> |
| Effects: Calls get(sb,widen('\n')) |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the <b>Effects</b> paragraph to:</p> |
| <blockquote> |
| Effects: Calls get(sb,this->widen('\n')) |
| </blockquote> |
| |
| <p><i>[Pre-Oxford: Minor correction from Howard: replaced 'widen' |
| with 'this->widen'.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious typo.</p> |
| <hr> |
| <a name="371"><h3>371. Stability of multiset and multimap member functions</h3></a><p><b>Section:</b> 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Frank Compagner <b>Date:</b> 20 Jul 2002</p> |
| <p> |
| The requirements for multiset and multimap containers (23.1 |
| [lib.containers.requirements], 23.1.2 [lib.associative.reqmnts], |
| 23.3.2 [lib.multimap] and 23.3.4 [lib.multiset]) make no mention of |
| the stability of the required (mutating) member functions. It appears |
| the standard allows these functions to reorder equivalent elements of |
| the container at will, yet the pervasive red-black tree implementation |
| appears to provide stable behaviour. |
| </p> |
| |
| <p>This is of most concern when considering the behaviour of erase(). |
| A stability requirement would guarantee the correct working of the |
| following 'idiom' that removes elements based on a certain predicate |
| function. |
| </p> |
| |
| <pre> multimap<int, int> m; |
| multimap<int, int>::iterator i = m.begin(); |
| while (i != m.end()) { |
| if (pred(i)) |
| m.erase (i++); |
| else |
| ++i; |
| } |
| </pre> |
| |
| <p> |
| Although clause 23.1.2/8 guarantees that i remains a valid iterator |
| througout this loop, absence of the stability requirement could |
| potentially result in elements being skipped. This would make |
| this code incorrect, and, furthermore, means that there is no way |
| of erasing these elements without iterating first over the entire |
| container, and second over the elements to be erased. This would |
| be unfortunate, and have a negative impact on both performance and |
| code simplicity. |
| </p> |
| |
| <p> |
| If the stability requirement is intended, it should be made explicit |
| (probably through an extra paragraph in clause 23.1.2). |
| </p> |
| <p> |
| If it turns out stability cannot be guaranteed, i'd argue that a |
| remark or footnote is called for (also somewhere in clause 23.1.2) to |
| warn against relying on stable behaviour (as demonstrated by the code |
| above). If most implementations will display stable behaviour, any |
| problems emerging on an implementation without stable behaviour will |
| be hard to track down by users. This would also make the need for an |
| erase_if() member function that much greater. |
| </p> |
| |
| <p>This issue is somewhat related to LWG issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">130</a>.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following to the end of 23.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> paragraph 4: |
| "For <tt>multiset</tt> and <tt>multimap</tt>, <tt>insert</tt>and <tt>erase</tt> |
| are <i>stable</i>: they preserve the relative ordering of equivalent |
| elements.</p> |
| |
| <p><i>[Lillehammer: Matt provided wording]</i></p> |
| <p><i>[Joe Gottman points out that the provided wording does not address |
| multimap and multiset. N1780 also addresses this issue and suggests |
| wording.]</i></p> |
| |
| <p><i>[Mont Tremblant: Changed set and map to multiset and multimap.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG agrees that this guarantee is necessary for common user |
| idioms to work, and that all existing implementations provide this |
| property. Note that this resolution guarantees stability for |
| multimap and multiset, not for all associative containers in |
| general.</p> |
| |
| <hr> |
| <a name="373"><h3>373. Are basic_istream and basic_ostream to use (exceptions()&badbit) != 0 ?</h3></a><p><b>Section:</b> 27.6.1.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.reqmts"> [lib.istream.formatted.reqmts]</a>, 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#WP">WP</a> <b>Submitter:</b> Keith Baker <b>Date:</b> 23 Jul 2002</p> |
| |
| <p> |
| In 27.6.1.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.reqmts"> [lib.istream.formatted.reqmts]</a> and 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> |
| (exception()&badbit) != 0 is used in testing for rethrow, yet |
| exception() is the constructor to class std::exception in 18.6.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.type.info"> [lib.type.info]</a> that has no return type. Should member function |
| exceptions() found in 27.4.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ios"> [lib.ios]</a> be used instead? |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.1.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.formatted.reqmts"> [lib.istream.formatted.reqmts]</a> and 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>, change |
| "(exception()&badbit) != 0" to "(exceptions()&badbit) != 0". |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious typo.</p> |
| <hr> |
| <a name="375"><h3>375. basic_ios should be ios_base in 27.7.1.3</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#WP">WP</a> <b>Submitter:</b> Ray Lischner <b>Date:</b> 14 Aug 2002</p> |
| <p> |
| In Section 27.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf.virtuals"> [lib.stringbuf.virtuals]</a>: Table 90, Table 91, and paragraph |
| 14 all contain references to "basic_ios::" which should be |
| "ios_base::". |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change all references to "basic_ios" in Table 90, Table 91, and |
| paragraph 14 to "ios_base". |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious typo.</p> |
| <hr> |
| <a name="376"><h3>376. basic_streambuf semantics</h3></a><p><b>Section:</b> 27.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf.virtuals"> [lib.stringbuf.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Ray Lischner <b>Date:</b> 14 Aug 2002</p> |
| <p> |
| In Section 27.7.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf.virtuals"> [lib.stringbuf.virtuals]</a>, Table 90, the implication is that |
| the four conditions should be mutually exclusive, but they are not. |
| The first two cases, as written, are subcases of the third.</p> |
| |
| <p> |
| As written, it is unclear what should be the result if cases 1 and 2 |
| are both true, but case 3 is false. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Rewrite these conditions as:</p> |
| <blockquote> |
| <p> |
| (which & (ios_base::in|ios_base::out)) == ios_base::in |
| </p> |
| |
| <p> |
| (which & (ios_base::in|ios_base::out)) == ios_base::out |
| </p> |
| |
| <p> |
| (which & (ios_base::in|ios_base::out)) == |
| (ios_base::in|ios_base::out) |
| and way == either ios_base::beg or ios_base::end |
| </p> |
| |
| <p>Otherwise</p> |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p>It's clear what we wanted to say, we just failed to say it. This |
| fixes it.</p> |
| <hr> |
| <a name="379"><h3>379. nonsensical ctype::do_widen() requirement</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 6 Sep 2002</p> |
| <p> |
| The last sentence in 22.2.1.1.2, p11 below doesn't seem to make sense. |
| </p> |
| <pre> charT do_widen (char c) const; |
| |
| -11- Effects: Applies the simplest reasonable transformation from |
| a char value or sequence of char values to the corresponding |
| charT value or values. The only characters for which unique |
| transformations are required are those in the basic source |
| character set (2.2). For any named ctype category with a |
| ctype<charT> facet ctw and valid ctype_base::mask value |
| M (is(M, c) || !ctw.is(M, do_widen(c))) is true. |
| </pre> |
| <p> |
| Shouldn't the last sentence instead read |
| </p> |
| <pre> For any named ctype category with a ctype<char> facet ctc |
| and valid ctype_base::mask value M |
| (ctc.is(M, c) || !is(M, do_widen(c))) is true. |
| </pre> |
| <p> |
| I.e., if the narrow character c is not a member of a class of |
| characters then neither is the widened form of c. (To paraphrase |
| footnote 224.) |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace the last sentence of 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>, p11 with the |
| following text: |
| </p> |
| <pre> For any named ctype category with a ctype<char> facet ctc |
| and valid ctype_base::mask value M, |
| (ctc.is(M, c) || !is(M, do_widen(c))) is true. |
| </pre> |
| |
| <p><i>[Kona: Minor edit. Added a comma after the <i>M</i> for clarity.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes this is just a typo, and that this is the correct fix.</p> |
| <hr> |
| <a name="380"><h3>380. typos in codecvt tables 53 and 54</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 6 Sep 2002</p> |
| <p> |
| Tables 53 and 54 in 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> are both titled "convert |
| result values," when surely "do_in/do_out result values" must have |
| been intended for Table 53 and "do_unshift result values" for Table |
| 54. |
| </p> |
| <p> |
| Table 54, row 3 says that the meaning of partial is "more characters |
| needed to be supplied to complete termination." The function is not |
| supplied any characters, it is given a buffer which it fills with |
| characters or, more precisely, destination elements (i.e., an escape |
| sequence). So partial means that space for more than (to_limit - to) |
| destination elements was needed to terminate a sequence given the |
| value of state. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the title of Table 53 to "do_in/do_out result values" and |
| the title of Table 54 to "do_unshift result values." |
| </p> |
| <p> |
| Change the text in Table 54, row 3 (the <b>partial</b> row), under the |
| heading Meaning, to "space for more than (to_limit - to) destination |
| elements was needed to terminate a sequence given the value of state." |
| </p> |
| <hr> |
| <a name="381"><h3>381. detection of invalid mbstate_t in codecvt</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 6 Sep 2002</p> |
| <p> |
| All but one codecvt member functions that take a state_type argument |
| list as one of their preconditions that the state_type argument have |
| a valid value. However, according to 22.2.1.5.2, p6, |
| codecvt::do_unshift() is the only codecvt member that is supposed to |
| return error if the state_type object is invalid. |
| </p> |
| |
| <p> |
| It seems to me that the treatment of state_type by all codecvt member |
| functions should be the same and the current requirements should be |
| changed. Since the detection of invalid state_type values may be |
| difficult in general or computationally expensive in some specific |
| cases, I propose the following: |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a new paragraph before 22.2.1.5.2, p5, and after the function |
| declaration below |
| </p> |
| <pre> result do_unshift(stateT& state, |
| externT* to, externT* to_limit, externT*& to_next) const; |
| </pre> |
| <p> |
| as follows: |
| </p> |
| <pre> Requires: (to <= to_end) well defined and true; state initialized, |
| if at the beginning of a sequence, or else equal to the result of |
| converting the preceding characters in the sequence. |
| </pre> |
| <p> |
| and change the text in Table 54, row 4, the <b>error</b> row, under |
| the heading Meaning, from |
| </p> |
| <pre> state has invalid value |
| </pre> |
| <p> |
| to |
| </p> |
| <pre> an unspecified error has occurred |
| </pre> |
| <p><b>Rationale:</b></p> |
| <p>The intent is that implementations should not be required to detect |
| invalid state values; such a requirement appears nowhere else. An |
| invalid state value is a precondition violation, <i>i.e.</i> undefined |
| behavior. Implementations that do choose to detect invalid state |
| values, or that choose to detect any other kind of error, may return |
| <b>error</b> as an indication.</p> |
| <hr> |
| <a name="383"><h3>383. Bidirectional iterator assertion typo</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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> ysapir (submitted via comp.std.c++) <b>Date:</b> 17 Oct 2002</p> |
| <p> |
| Following a discussion on the boost list regarding end iterators and |
| the possibility of performing operator--() on them, it seems to me |
| that there is a typo in the standard. This typo has nothing to do |
| with that discussion. |
| </p> |
| |
| <p> |
| I have checked this newsgroup, as well as attempted a search of the |
| Active/Defect/Closed Issues List on the site for the words "s is |
| derefer" so I believe this has not been proposed before. Furthermore, |
| the "Lists by Index" mentions only DR <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a> on section |
| 24.1.4, and DR <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a> is not related to this issue. |
| </p> |
| |
| <p> |
| The standard makes the following assertion on bidirectional iterators, |
| in section 24.1.4 [lib.bidirectional.iterators], Table 75: |
| </p> |
| |
| <pre> operational assertion/note |
| expression return type semantics pre/post-condition |
| |
| --r X& pre: there exists s such |
| that r == ++s. |
| post: s is dereferenceable. |
| --(++r) == r. |
| --r == --s implies r == s. |
| &r == &--r. |
| </pre> |
| |
| <p> |
| (See <a href="http://aspn.activestate.com/ASPN/Mail/Message/boost/1395763">http://aspn.activestate.com/ASPN/Mail/Message/boost/1395763</a>.) |
| </p> |
| |
| <p> |
| In particular, "s is dereferenceable" seems to be in error. It seems |
| that the intention was to say "r is dereferenceable". |
| </p> |
| |
| <p> |
| If it were to say "r is dereferenceable" it would |
| make perfect sense. Since s must be dereferenceable prior to |
| operator++, then the natural result of operator-- (to undo operator++) |
| would be to make r dereferenceable. Furthermore, without other |
| assertions, and basing only on precondition and postconditions, we |
| could not otherwise know this. So it is also interesting information. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the guarantee to "postcondition: r is dereferenceable." |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious typo</p> |
| <hr> |
| <a name="384"><h3>384. equal_range has unimplementable runtime complexity</h3></a><p><b>Section:</b> 25.3.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.equal.range"> [lib.equal.range]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Hans Bos <b>Date:</b> 18 Oct 2002</p> |
| <p> |
| Section 25.3.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.equal.range"> [lib.equal.range]</a> |
| states that at most 2 * log(last - first) + 1 |
| comparisons are allowed for equal_range. |
| </p> |
| |
| <p>It is not possible to implement equal_range with these constraints.</p> |
| |
| <p>In a range of one element as in:</p> |
| <pre> int x = 1; |
| equal_range(&x, &x + 1, 1) |
| </pre> |
| |
| <p>it is easy to see that at least 2 comparison operations are needed.</p> |
| |
| <p>For this case at most 2 * log(1) + 1 = 1 comparison is allowed.</p> |
| |
| <p>I have checked a few libraries and they all use the same (nonconforming) |
| algorithm for equal_range that has a complexity of</p> |
| <pre> 2* log(distance(first, last)) + 2. |
| </pre> |
| <p>I guess this is the algorithm that the standard assumes for equal_range.</p> |
| |
| <p> |
| It is easy to see that 2 * log(distance) + 2 comparisons are enough |
| since equal range can be implemented with lower_bound and upper_bound |
| (both log(distance) + 1). |
| </p> |
| |
| <p> |
| I think it is better to require something like 2log(distance) + O(1) (or |
| even logarithmic as multiset::equal_range). |
| Then an implementation has more room to optimize for certain cases (e.g. |
| have log(distance) characteristics when at most match is found in the range |
| but 2log(distance) + 4 for the worst case). |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.3.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.lower.bound"> [lib.lower.bound]</a>/4, change <tt>log(last - first) + 1</tt> |
| to <tt>log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p> |
| |
| <p>In 25.3.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.upper.bound"> [lib.upper.bound]</a>/4, change <tt>log(last - first) + 1</tt> |
| to <tt>log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p> |
| |
| <p>In 25.3.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.equal.range"> [lib.equal.range]</a>/4, change <tt>2*log(last - first) + 1</tt> |
| to <tt>2*log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p> |
| |
| <p><i>[Matt provided wording]</i></p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered just saying <i>O</i>(log n) for all three, but |
| Ê decided that threw away too much valuable information.Ê The fact |
| Ê that lower_bound is twice as fast as equal_range is important. |
| Ê However, it's better to allow an arbitrary additive constant than to |
| Ê specify an exact count.Ê An exact count would have to |
| Ê involve <tt>floor</tt> or <tt>ceil</tt>.Ê It would be too easy to |
| Ê get this wrong, and don't provide any substantial value for users.</p> |
| <hr> |
| <a name="386"><h3>386. Reverse iterator's operator[] has impossible return type</h3></a><p><b>Section:</b> 24.4.1.3.11 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.op-="> [lib.reverse.iter.op-=]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 23 Oct 2002</p> |
| <p>In 24.4.1.3.11 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.op-="> [lib.reverse.iter.op-=]</a>, <tt>reverse_iterator<>::operator[]</tt> |
| is specified as having a return type of <tt>reverse_iterator::reference</tt>, |
| which is the same as <tt>iterator_traits<Iterator>::reference</tt>. |
| (Where <tt>Iterator</tt> is the underlying iterator type.)</p> |
| |
| <p>The trouble is that <tt>Iterator</tt>'s own operator[] doesn't |
| necessarily have a return type |
| of <tt>iterator_traits<Iterator>::reference</tt>. Its |
| return type is merely required to be convertible |
| to <tt>Iterator</tt>'s value type. The return type specified for |
| reverse_iterator's operator[] would thus appear to be impossible.</p> |
| |
| <p>With the resolution of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a>, the type of |
| <tt>a[n]</tt> will continue to be required (for random access |
| iterators) to be convertible to the value type, and also <tt>a[n] = |
| t</tt> will be a valid expression. Implementations of |
| <tt>reverse_iterator</tt> will likely need to return a proxy from |
| <tt>operator[]</tt> to meet these requirements. As mentioned in the |
| comment from Dave Abrahams, the simplest way to specify that |
| <tt>reverse_iterator</tt> meet this requirement to just mandate |
| it and leave the return type of <tt>operator[]</tt> unspecified.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>In 24.4.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.reverse.iter.requirements"> [lib.reverse.iter.requirements]</a> change:</p> |
| |
| <blockquote> |
| <pre>reference operator[](difference_type n) const; |
| </pre> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <pre><b><i>unspecified</i></b> operator[](difference_type n) const; // see <font color="red">lib.random.access.iterators</font> |
| </pre> |
| </blockquote> |
| |
| |
| |
| |
| <p><i>[ |
| Comments from Dave Abrahams: IMO we should resolve 386 by just saying |
| that the return type of reverse_iterator's operator[] is |
| unspecified, allowing the random access iterator requirements to |
| impose an appropriate return type. If we accept 299's proposed |
| resolution (and I think we should), the return type will be |
| readable and writable, which is about as good as we can do. |
| ]</i></p> |
| <hr> |
| <a name="389"><h3>389. Const overload of valarray::operator[] returns by value</h3></a><p><b>Section:</b> 26.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex"> [lib.complex]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Gabriel Dos Reis <b>Date:</b> 8 Nov 2002</p> |
| <p>Consider the following program:</p> |
| <pre> #include <iostream> |
| #include <ostream> |
| #include <vector> |
| #include <valarray> |
| #include <algorithm> |
| #include <iterator> |
| template<typename Array> |
| void print(const Array& a) |
| { |
| using namespace std; |
| typedef typename Array::value_type T; |
| copy(&a[0], &a[0] + a.size(), |
| ostream_iterator<T>(std::cout, " ")); |
| } |
| template<typename T, unsigned N> |
| unsigned size(T(&)[N]) { return N; } |
| int main() |
| { |
| double array[] = { 0.89, 9.3, 7, 6.23 }; |
| std::vector<double> v(array, array + size(array)); |
| std::valarray<double> w(array, size(array)); |
| print(v); // #1 |
| std::cout << std::endl; |
| print(w); // #2 |
| std::cout << std::endl; |
| } |
| </pre> |
| |
| <p>While the call numbered #1 succeeds, the call numbered #2 fails |
| because the const version of the member function |
| valarray<T>::operator[](size_t) returns a value instead of a |
| const-reference. That seems to be so for no apparent reason, no |
| benefit. Not only does that defeats users' expectation but it also |
| does hinder existing software (written either in C or Fortran) |
| integration within programs written in C++. There is no reason why |
| subscripting an expression of type valarray<T> that is const-qualified |
| should not return a const T&.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In the class synopsis in 26.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.complex"> [lib.complex]</a>, and in |
| <font color="red">26.3.2.3</font> just above paragraph 1, change</p> |
| <pre> T operator[](size_t const); |
| </pre> |
| <p>to</p> |
| <pre> const T& operator[](size_t const); |
| </pre> |
| |
| <p><i>[Kona: fixed a minor typo: put semicolon at the end of the line |
| wehre it belongs.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>Return by value seems to serve no purpose. Valaray was explicitly |
| designed to have a specified layout so that it could easily be |
| integrated with libraries in other languages, and return by value |
| defeats that purpose. It is believed that this change will have no |
| impact on allowable optimizations.</p> |
| <hr> |
| <a name="391"><h3>391. non-member functions specified as const</h3></a><p><b>Section:</b> 22.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.conversions"> [lib.conversions]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> James Kanze <b>Date:</b> 10 Dec 2002</p> |
| <p> |
| The specifications of toupper and tolower both specify the functions as |
| const, althought they are not member functions, and are not specified as |
| const in the header file synopsis in section 22.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locales"> [lib.locales]</a>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.3.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.conversions"> [lib.conversions]</a>, remove <tt>const</tt> from the function |
| declarations of std::toupper and std::tolower</p> |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious typo</p> |
| <hr> |
| <a name="395"><h3>395. inconsistencies in the definitions of rand() and random_shuffle()</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#WP">WP</a> <b>Submitter:</b> James Kanze <b>Date:</b> 3 Jan 2003</p> |
| <p> |
| In 26.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-numerics.html#lib.numarray"> [lib.numarray]</a>, the C++ standard refers to the C standard for the |
| definition of rand(); in the C standard, it is written that "The |
| implementation shall behave as if no library function calls the rand |
| function." |
| </p> |
| |
| <p> |
| In 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>, there is no specification as to |
| how the two parameter version of the function generates its random |
| value. I believe that all current implementations in fact call rand() |
| (in contradiction with the requirement avove); if an implementation does |
| not call rand(), there is the question of how whatever random generator |
| it does use is seeded. Something is missing. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In [lib.c.math], add a paragraph specifying that the C definition of |
| rand shal be modified to say that "Unless otherwise specified, the |
| implementation shall behave as if no library function calls the rand |
| function." |
| </p> |
| |
| <p> |
| In [lib.alg.random.shuffle], add a sentence to the effect that "In |
| the two argument form of the function, the underlying source of |
| random numbers is implementation defined. [Note: in particular, an |
| implementation is permitted to use <tt>rand</tt>.] |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution proposed requiring the |
| two-argument from of <tt>random_shuffle</tt> to |
| use <tt>rand</tt>. We don't want to do that, because some existing |
| implementations already use something else: gcc |
| uses <tt>lrand48</tt>, for example. Using <tt>rand</tt> presents a |
| problem if the number of elements in the sequence is greater than |
| RAND_MAX.</p> |
| <hr> |
| <a name="400"><h3>400. redundant type cast in lib.allocator.members</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#WP">WP</a> <b>Submitter:</b> Markus Mauhart <b>Date:</b> 27 Feb 2003</p> |
| <p> |
| 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> allocator members, contains |
| the following 3 lines: |
| </p> |
| |
| <pre> 12 Returns: new((void *) p) T( val) |
| void destroy(pointer p); |
| 13 Returns: ((T*) p)->~T() |
| </pre> |
| |
| <p> |
| The type cast "(T*) p" in the last line is redundant cause |
| we know that std::allocator<T>::pointer is a typedef for T*. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace "((T*) p)" with "p". |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>Just a typo, this is really editorial.</p> |
| <hr> |
| <a name="402"><h3>402. wrong new expression in [some_]allocator::construct</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>, 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#WP">WP</a> <b>Submitter:</b> Markus Mauhart <b>Date:</b> 27 Feb 2003</p> |
| <p> |
| This applies to the new expression that is contained in both par12 of |
| 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> and in par2 (table 32) 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>. |
| I think this new expression is wrong, involving unintended side |
| effects. |
| </p> |
| |
| |
| <p>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> contains the following 3 lines:</p> |
| |
| <pre> 11 Returns: the largest value N for which the call allocate(N,0) might succeed. |
| void construct(pointer p, const_reference val); |
| 12 Returns: new((void *) p) T( val) |
| </pre> |
| |
| |
| <p>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> in table 32 has the following line:</p> |
| <pre> a.construct(p,t) Effect: new((void*)p) T(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> |
| Cause of using "new" but not "::new", any existing "T::operator new" |
| function will hide the global placement new function. When there is no |
| "T::operator new" with adequate signature, |
| every_alloc<T>::construct(..) is ill-formed, and most |
| std::container<T,every_alloc<T>> use it; a workaround |
| would be adding placement new and delete functions with adequate |
| signature and semantic to class T, but class T might come from another |
| party. Maybe even worse is the case when T has placement new and |
| delete functions with adequate signature but with "unknown" semantic: |
| I dont like to speculate about it, but whoever implements |
| any_container<T,any_alloc> and wants to use construct(..) |
| probably must think about it. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace "new" with "::new" in both cases. |
| </p> |
| <hr> |
| <a name="403"><h3>403. basic_string::swap should not throw exceptions</h3></a><p><b>Section:</b> 21.3.5.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::swap"> [lib.string::swap]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 25 Mar 2003</p> |
| |
| <p> |
| std::basic_string, 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a> paragraph 2 says that |
| basic_string "conforms to the requirements of a Sequence, as specified |
| in (23.1.1)." The sequence requirements specified in (23.1.1) to not |
| include any prohibition on swap members throwing exceptions. |
| </p> |
| |
| <p> |
| Section 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> paragraph 10 does limit conditions under |
| which exceptions may be thrown, but applies only to "all container |
| types defined in this clause" and so excludes basic_string::swap |
| because it is defined elsewhere. |
| </p> |
| |
| <p> |
| Eric Niebler points out that 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a> paragraph 5 explicitly |
| permits basic_string::swap to invalidates iterators, which is |
| disallowed by 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> paragraph 10. Thus the standard would |
| be contradictory if it were read or extended to read as having |
| basic_string meet 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> paragraph 10 requirements. |
| </p> |
| |
| <p> |
| Yet several LWG members have expressed the belief that the original |
| intent was that basic_string::swap should not throw exceptions as |
| specified by 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> paragraph 10, and that the standard is |
| unclear on this issue. The complexity of basic_string::swap is |
| specified as "constant time", indicating the intent was to avoid |
| copying (which could cause a bad_alloc or other exception). An |
| important use of swap is to ensure that exceptions are not thrown in |
| exception-safe code. |
| </p> |
| |
| <p> |
| Note: There remains long standing concern over whether or not it is |
| possible to reasonably meet the 23.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> paragraph 10 swap |
| requirements when allocators are unequal. The specification of |
| basic_string::swap exception requirements is in no way intended to |
| address, prejudice, or otherwise impact that concern. |
| </p> |
| |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 21.3.5.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::swap"> [lib.string::swap]</a>, add a throws clause: |
| </p> |
| |
| <p> |
| Throws: Shall not throw exceptions. |
| </p> |
| <hr> |
| <a name="404"><h3>404. May a replacement allocation function be declared inline?</h3></a><p><b>Section:</b> 17.4.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.replacement.functions"> [lib.replacement.functions]</a>, 18.5.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete"> [lib.new.delete]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 24 Apr 2003</p> |
| <p> |
| The eight basic dynamic memory allocation functions (single-object |
| and array versions of ::operator new and ::operator delete, in the |
| ordinary and nothrow forms) are replaceable. A C++ program may |
| provide an alternative definition for any of them, which will be used |
| in preference to the implementation's definition. |
| </p> |
| |
| <p> |
| Three different parts of the standard mention requirements on |
| replacement functions: 17.4.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.replacement.functions"> [lib.replacement.functions]</a>, 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> |
| and 18.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.new.delete.array"> [lib.new.delete.array]</a>, and 3.7.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/basic.html#basic.stc.dynamic"> [basic.stc.dynamic]</a>. |
| </p> |
| |
| <p>None of these three places say whether a replacement function may |
| be declared inline. 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> paragraph 2 specifies a |
| signature for the replacement function, but that's not enough: |
| the <tt>inline</tt> specifier is not part of a function's signature. |
| One might also reason from 7.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/dcl.html#dcl.fct.spec"> [dcl.fct.spec]</a> paragraph 2, which |
| requires that "an inline function shall be defined in every |
| translation unit in which it is used," but this may not be quite |
| specific enough either. We should either explicitly allow or |
| explicitly forbid inline replacement memory allocation |
| functions.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a new sentence to the end of 17.4.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.replacement.functions"> [lib.replacement.functions]</a> paragraph 3: |
| "The program's definitions shall not be specified as <tt>inline</tt>. |
| No diagnostic is required." |
| </p> |
| |
| <p><i>[Kona: added "no diagnostic is required"]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| The fact that <tt>inline</tt> isn't mentioned appears to have been |
| nothing more than an oversight. Existing implementations do not |
| permit inline functions as replacement memory allocation functions. |
| Providing this functionality would be difficult in some cases, and is |
| believed to be of limited value. |
| </p> |
| <hr> |
| <a name="405"><h3>405. qsort and POD</h3></a><p><b>Section:</b> 25.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.c.library"> [lib.alg.c.library]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Ray Lischner <b>Date:</b> 08 Apr 2003</p> |
| <p> |
| Section 25.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.c.library"> [lib.alg.c.library]</a> describes bsearch and qsort, from the C |
| standard library. Paragraph 4 does not list any restrictions on qsort, |
| but it should limit the base parameter to point to POD. Presumably, |
| qsort sorts the array by copying bytes, which requires POD. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 25.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.c.library"> [lib.alg.c.library]</a> paragraph 4, just after the declarations and |
| before the nonnormative note, add these words: "both of which have the |
| same behavior as the original declaration. The behavior is undefined |
| unless the objects in the array pointed to by <i>base</i> are of POD |
| type." |
| </p> |
| |
| <p><i>[Something along these lines is clearly necessary. Matt |
| provided wording.]</i></p> |
| <hr> |
| <a name="406"><h3>406. vector::insert(s) exception safety</h3></a><p><b>Section:</b> 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.stack"> [lib.stack]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 27 Apr 2003</p> |
| <p> |
| There is a possible defect in the standard: the standard text was |
| never intended to prevent arbitrary ForwardIterators, whose operations |
| may throw exceptions, from being passed, and it also wasn't intended |
| to require a temporary buffer in the case where ForwardIterators were |
| passed (and I think most implementations don't use one). As is, the |
| standard appears to impose requirements that aren't met by any |
| existing implementation. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.stack"> [lib.stack]</a> paragraph 1 with:</p> |
| <blockquote> |
| 1- Notes: Causes reallocation if the new size is greater than the |
| old capacity. If no reallocation happens, all the iterators and |
| references before the insertion point remain valid. If an exception |
| is thrown other than by the copy constructor or assignment operator |
| of T or by any InputIterator operation there are no effects. |
| </blockquote> |
| |
| <p><i>[We probably need to say something similar for deque.]</i></p> |
| |
| <hr> |
| <a name="407"><h3>407. Can singular iterators be destroyed?</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#WP">WP</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 3 June 2003</p> |
| <p> |
| Clause 24.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>, paragraph 5, says that the only expression |
| that is defined for a singular iterator is "an assignment of a |
| non-singular value to an iterator that holds a singular value". This |
| means that destroying a singular iterator (e.g. letting an automatic |
| variable go out of scope) is technically undefined behavior. This |
| seems overly strict, and probably unintentional. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the sentence in question to "... the only exceptions are |
| destroying an iterator that holds a singular value, or the assignment |
| of a non-singular value to an iterator that holds a singular value." |
| </p> |
| <hr> |
| <a name="409"><h3>409. Closing an fstream should clear error state</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>, 27.8.1.10 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ofstream.members"> [lib.ofstream.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 3 June 2003</p> |
| <p> |
| A strict reading of 27.8.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstreams"> [lib.fstreams]</a> shows that opening or |
| closing a basic_[io]fstream does not affect the error bits. This |
| means, for example, that if you read through a file up to EOF, and |
| then close the stream and reopen it at the beginning of the file, |
| the EOF bit in the stream's error state is still set. This is |
| counterintuitive. |
| </p> |
| <p> |
| The LWG considered this issue once before, as issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#22">22</a>, |
| and put in a footnote to clarify that the strict reading was indeed |
| correct. We did that because we believed the standard was |
| unambiguous and consistent, and that we should not make architectural |
| changes in a TC. Now that we're working on a new revision of the |
| language, those considerations no longer apply. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change 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>, para. 3 from:</p> |
| |
| <blockquote> |
| Calls rdbuf()->open(s,mode|in). If that function returns a null |
| pointer, calls setstate(failbit) (which may throw ios_base::failure |
| [Footnote: (lib.iostate.flags)]. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote>Calls rdbuf()->open(s,mode|in). If that function returns |
| a null pointer, calls setstate(failbit) (which may throw |
| ios_base::failure [Footnote: (lib.iostate.flags)), else calls clear(). |
| </blockquote> |
| |
| <p>Change 27.8.1.10 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ofstream.members"> [lib.ofstream.members]</a>, para. 3 from:</p> |
| |
| <blockquote>Calls rdbuf()->open(s,mode|out). If that function |
| returns a null pointer, calls setstate(failbit) (which may throw |
| ios_base::failure [Footnote: (lib.iostate.flags)). |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote>Calls rdbuf()->open(s,mode|out). If that function |
| returns a null pointer, calls setstate(failbit) (which may throw |
| ios_base::failure [Footnote: (lib.iostate.flags)), else calls clear(). |
| </blockquote> |
| |
| <p>Change 27.8.1.13 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstream.members"> [lib.fstream.members]</a>, para. 3 from:</p> |
| |
| <blockquote>Calls rdbuf()->open(s,mode), If that function returns a |
| null pointer, calls setstate(failbit), (which may throw |
| ios_base::failure). (lib.iostate.flags) ) |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote>Calls rdbuf()->open(s,mode), If that function returns a |
| null pointer, calls setstate(failbit), (which may throw |
| ios_base::failure). (lib.iostate.flags) ), else calls clear(). |
| </blockquote> |
| |
| |
| |
| <p><i>[Kona: the LWG agrees this is a good idea. Post-Kona: Bill |
| provided wording. He suggests having open, not close, clear the error |
| flags.]</i></p> |
| |
| <p><i>[Post-Sydney: Howard provided a new proposed resolution. The |
| old one didn't make sense because it proposed to fix this at the |
| level of basic_filebuf, which doesn't have access to the stream's |
| error state. Howard's proposed resolution fixes this at the level |
| of the three fstream class template instead.]</i></p> |
| |
| <hr> |
| <a name="410"><h3>410. Missing semantics for stack and queue comparison operators</h3></a><p><b>Section:</b> 23.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.cons"> [lib.list.cons]</a>, 23.2.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.modifiers"> [lib.list.modifiers]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Hans Bos <b>Date:</b> 7 Jun 2003</p> |
| <p> |
| Sections 23.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.cons"> [lib.list.cons]</a> and 23.2.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.modifiers"> [lib.list.modifiers]</a> list |
| comparison operators (==, !=, <, <=, >, =>) for queue and |
| stack. Only the semantics for queue::operator== (23.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.cons"> [lib.list.cons]</a> par2) and queue::operator< (23.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.cons"> [lib.list.cons]</a> |
| par3) are defined. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following new paragraphs after 23.2.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.cons"> [lib.list.cons]</a> |
| paragraph 3:</p> |
| |
| <blockquote> |
| |
| <pre> operator!= |
| </pre> |
| <p>Returns: <tt>x.c != y.c</tt></p> |
| |
| <pre> operator> |
| </pre> |
| <p>Returns: <tt>x.c > y.c</tt></p> |
| |
| <pre> operator<= |
| </pre> |
| <p>Returns: <tt>x.c <= y.c</tt></p> |
| |
| <pre> operator>= |
| </pre> |
| <p>Returns: <tt>x.c >= y.c</tt></p> |
| |
| </blockquote> |
| |
| <p>Add the following paragraphs at the end of 23.2.3.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.list.modifiers"> [lib.list.modifiers]</a>:</p> |
| |
| <blockquote> |
| |
| <pre> operator== |
| </pre> |
| <p>Returns: <tt>x.c == y.c</tt></p> |
| |
| <pre> operator< |
| </pre> |
| <p>Returns: <tt>x.c < y.c</tt></p> |
| |
| <pre> operator!= |
| </pre> |
| <p>Returns: <tt>x.c != y.c</tt></p> |
| |
| <pre> operator> |
| </pre> |
| <p>Returns: <tt>x.c > y.c</tt></p> |
| |
| <pre> operator<= |
| </pre> |
| <p>Returns: <tt>x.c <= y.c</tt></p> |
| |
| <pre> operator>= |
| </pre> |
| <p>Returns: <tt>x.c >= y.c</tt></p> |
| |
| </blockquote> |
| |
| |
| <p><i>[Kona: Matt provided wording.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| There isn't any real doubt about what these operators are |
| supposed to do, but we ought to spell it out. |
| <hr> |
| <a name="411"><h3>411. Wrong names of set member functions</h3></a><p><b>Section:</b> 25.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.set.operations"> [lib.alg.set.operations]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Daniel Frey <b>Date:</b> 9 Jul 2003</p> |
| <p> |
| 25.3.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.set.operations"> [lib.alg.set.operations]</a> paragraph 1 reads: |
| "The semantics of the set operations are generalized to multisets in a |
| standard way by defining union() to contain the maximum number of |
| occurrences of every element, intersection() to contain the minimum, and |
| so on." |
| </p> |
| |
| <p> |
| This is wrong. The name of the functions are set_union() and |
| set_intersection(), not union() and intersection(). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change that sentence to use the correct names.</p> |
| <hr> |
| <a name="412"><h3>412. Typo in 27.4.4.3</h3></a><p><b>Section:</b> 27.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostate.flags"> [lib.iostate.flags]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 10 Jul 2003</p> |
| <p> |
| The Effects clause in 27.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostate.flags"> [lib.iostate.flags]</a> paragraph 5 says that the |
| function only throws if the respective bits are already set prior to |
| the function call. That's obviously not the intent. The typo ought to |
| be corrected and the text reworded as: "If (<i>state</i> & |
| exceptions()) == 0, returns. ..." |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostate.flags"> [lib.iostate.flags]</a> paragraph 5, replace "If (rdstate() & |
| exceptions()) == 0" with "If ((state | (rdbuf() ? goodbit : badbit)) |
| & exceptions()) == 0". |
| </p> |
| |
| <p><i>[Kona: the original proposed resolution wasn't quite right. We |
| really do mean rdstate(); the ambiguity is that the wording in the |
| standard doesn't make it clear whether we mean rdstate() before |
| setting the new state, or rdsate() after setting it. We intend the |
| latter, of course. Post-Kona: Martin provided wording.]</i></p> |
| |
| <hr> |
| <a name="413"><h3>413. Proposed resolution to LDR#64 still wrong</h3></a><p><b>Section:</b> 27.6.1.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream::extractors"> [lib.istream::extractors]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Bo Persson <b>Date:</b> 13 Jul 2003</p> |
| <p> |
| The second sentence of the proposed resolution says: |
| </p> |
| |
| <p> |
| "If it inserted no characters because it caught an exception thrown |
| while extracting characters from sb and ..." |
| </p> |
| |
| <p> |
| However, we are not extracting from sb, but extracting from the |
| basic_istream (*this) and inserting into sb. I can't really tell if |
| "extracting" or "sb" is a typo. |
| </p> |
| |
| <p><i>[ |
| Sydney: Definitely a real issue. We are, indeed, extracting characters |
| from an istream and not from sb. The problem was there in the FDIS and |
| wasn't fixed by issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#64">64</a>. Probably what was intended was |
| to have *this instead of sb. We're talking about the exception flag |
| state of a basic_istream object, and there's only one basic_istream |
| object in this discussion, so that would be a consistent |
| interpretation. (But we need to be careful: the exception policy of |
| this member function must be consistent with that of other |
| extractors.) PJP will provide wording. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the sentence from:</p> |
| |
| <blockquote> |
| If it inserted no characters because it caught an exception thrown |
| while extracting characters from sb and failbit is on in exceptions(), |
| then the caught exception is rethrown. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| If it inserted no characters because it caught an exception thrown |
| while extracting characters from *this and failbit is on in exceptions(), |
| then the caught exception is rethrown. |
| </blockquote> |
| <hr> |
| <a name="414"><h3>414. Which iterators are invalidated by v.erase()?</h3></a><p><b>Section:</b> 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.stack"> [lib.stack]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 19 Aug 2003</p> |
| <p> |
| Consider the following code fragment: |
| </p> |
| <blockquote> |
| <pre>int A[8] = { 1,3,5,7,9,8,4,2 }; |
| std::vector<int> v(A, A+8); |
| |
| std::vector<int>::iterator i1 = v.begin() + 3; |
| std::vector<int>::iterator i2 = v.begin() + 4; |
| v.erase(i1); |
| </pre> |
| </blockquote> |
| |
| <p> |
| Which iterators are invalidated by <tt>v.erase(i1)</tt>: i1, i2, |
| both, or neither? |
| </p> |
| |
| <p> |
| On all existing implementations that I know of, the status of i1 and |
| i2 is the same: both of them will be iterators that point to some |
| elements of the vector (albeit not the same elements they did |
| before). You won't get a crash if you use them. Depending on |
| exactly what you mean by "invalidate", you might say that neither one |
| has been invalidated because they still point to <i>something</i>, |
| or you might say that both have been invalidated because in both |
| cases the elements they point to have been changed out from under the |
| iterator. |
| </p> |
| |
| <p> |
| The standard doesn't say either of those things. It says that erase |
| invalidates all iterators and references "after the point of the |
| erase". This doesn't include i1, since it's at the point of the |
| erase instead of after it. I can't think of any sensible definition |
| of invalidation by which one can say that i2 is invalidated but i1 |
| isn't. |
| </p> |
| |
| <p> |
| (This issue is important if you try to reason about iterator validity |
| based only on the guarantees in the standard, rather than reasoning |
| from typical implementation techniques. Strict debugging modes, |
| which some programmers find useful, do not use typical implementation |
| techniques.) |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 23.2.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.stack"> [lib.stack]</a> paragraph 3, change "Invalidates all the |
| iterators and references after the point of the erase" to |
| "Invalidates iterators and references at or after the point of the |
| erase". |
| </p> |
| <p><b>Rationale:</b></p> |
| <p>I believe this was essentially a typographical error, and that it |
| was taken for granted that erasing an element invalidates iterators |
| that point to it. The effects clause in question treats iterators |
| and references in parallel, and it would seem counterintuitive to |
| say that a reference to an erased value remains valid.</p> |
| <hr> |
| <a name="415"><h3>415. behavior of std::ws</h3></a><p><b>Section:</b> 27.6.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.manip"> [lib.istream.manip]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p> |
| <p> |
| According to 27.6.1.4, the ws() manipulator is not required to construct |
| the sentry object. The manipulator is also not a member function so the |
| text in 27.6.1, p1 through 4 that describes the exception policy for |
| istream member functions does not apply. That seems inconsistent with |
| the rest of extractors and all the other input functions (i.e., ws will |
| not cause a tied stream to be flushed before extraction, it doesn't check |
| the stream's exceptions or catch exceptions thrown during input, and it |
| doesn't affect the stream's gcount). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to 27.6.1.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.istream.manip"> [lib.istream.manip]</a>, immediately before the first sentence |
| of paragraph 1, the following text: |
| </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 is.gcount(). After constructing a sentry |
| object... |
| </blockquote> |
| |
| <p><i>[Post-Kona: Martin provided wording]</i></p> |
| |
| <hr> |
| <a name="420"><h3>420. is std::FILE a complete type?</h3></a><p><b>Section:</b> 27.8.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstreams"> [lib.fstreams]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p> |
| <p> |
| 7.19.1, p2, of C99 requires that the FILE type only be declared in |
| <stdio.h>. None of the (implementation-defined) members of the |
| struct is mentioned anywhere for obvious reasons. |
| </p> |
| |
| <p> |
| C++ says in 27.8.1, p2 that FILE is a type that's defined in <cstdio>. Is |
| it really the intent that FILE be a complete type or is an implementation |
| allowed to just declare it without providing a full definition? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In the first sentence of 27.8.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstreams"> [lib.fstreams]</a> paragraph 2, change |
| "defined" to "declared".</p> |
| <p><b>Rationale:</b></p> |
| <p>We don't want to impose any restrictions beyond what the C standard |
| already says. We don't want to make anything implementation defined, |
| because that imposes new requirements in implementations.</p> |
| <hr> |
| <a name="425"><h3>425. return value of std::get_temporary_buffer</h3></a><p><b>Section:</b> 20.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.help"> [lib.meta.help]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p> |
| <p> |
| The standard is not clear about the requirements on the value returned from |
| a call to get_temporary_buffer(0). In particular, it fails to specify whether |
| the call should return a distinct pointer each time it is called (like |
| operator new), or whether the value is unspecified (as if returned by |
| malloc). The standard also fails to mention what the required behavior |
| is when the argument is less than 0. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 20.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-utilities.html#lib.meta.help"> [lib.meta.help]</a> paragraph 2 from "...or a pair of 0 |
| values if no storage can be obtained" to "...or a pair of 0 values if |
| no storage can be obtained or if <i>n</i> <= 0."</p> |
| <p><i>[Kona: Matt provided wording]</i></p> |
| <hr> |
| <a name="426"><h3>426. search_n(), fill_n(), and generate_n() with negative n</h3></a><p><b>Section:</b> 25.1.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.search"> [lib.alg.search]</a>, 25.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.fill"> [lib.alg.fill]</a>, 25.2.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.generate"> [lib.alg.generate]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p> |
| <p> |
| The complexity requirements for these function templates are incorrect |
| (or don't even make sense) for negative n:</p> |
| |
| <p>25.1.9, p7 (search_n): |
| <br> |
| Complexity: At most (last1 - first1) * count applications |
| of the corresponding predicate.</p> |
| |
| <p>25.2.5, p3 (fill_n): |
| <br> |
| Complexity: Exactly last - first (or n) assignments.</p> |
| <br> |
| |
| <p>25.2.6, p3 (generate_n): |
| <br> |
| Complexity: Exactly last - first (or n) assignments.</p> |
| |
| <p> |
| In addition, the Requirements or the Effects clauses for the latter two |
| templates don't say anything about the behavior when n is negative. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.1.9, p7 to</p> |
| |
| <blockquote> |
| Complexity: At most (last1 - first1) * count applications |
| of the corresponding predicate if count is positive, |
| or 0 otherwise. |
| </blockquote> |
| |
| <p>Change 25.2.5, p2 to</p> |
| <blockquote> |
| Effects: Assigns value through all the iterators in the range [first, |
| last), or [first, first + n) if n is positive, none otherwise. |
| </blockquote> |
| |
| <p>Change 25.2.5, p3 to:</p> |
| <blockquote> |
| Complexity: Exactly last - first (or n if n is positive, |
| or 0 otherwise) assignments. |
| </blockquote> |
| |
| <p> |
| Change 25.2.6, p1 |
| to (notice the correction for the misspelled "through"): |
| </p> |
| <blockquote> |
| Effects: Invokes the function object genand assigns the return |
| value of gen through all the iterators in the range [first, last), |
| or [first, first + n) if n is positive, or [first, first) |
| otherwise. |
| </blockquote> |
| |
| <p>Change 25.2.6, p3 to:</p> |
| <blockquote> |
| Complexity: Exactly last - first (or n if n is positive, |
| or 0 otherwise) assignments. |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p>Informally, we want to say that whenever we see a negative number |
| we treat it the same as if it were zero. We believe the above |
| changes do that (although they may not be the minimal way of saying |
| so). The LWG considered and rejected the alternative of saying that |
| negative numbers are undefined behavior.</p> |
| <hr> |
| <a name="428"><h3>428. string::erase(iterator) validity</h3></a><p><b>Section:</b> 21.3.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::erase"> [lib.string::erase]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2003</p> |
| <p> |
| 23.1.1, p3 along with Table 67 specify as a prerequisite for a.erase(q) |
| that q must be a valid dereferenceable iterator into the sequence a. |
| </p> |
| |
| <p> |
| However, 21.3.5.5, p5 describing string::erase(p) only requires that |
| p be a valid iterator. |
| </p> |
| |
| <p> |
| This may be interepreted as a relaxation of the general requirement, |
| which is most likely not the intent. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove 21.3.5.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::erase"> [lib.string::erase]</a> paragraph 5.</p> |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered two options: changing the string requirements to |
| match the general container requirements, or just removing the |
| erroneous string requirements altogether. The LWG chose the latter |
| option, on the grounds that duplicating text always risks the |
| possibility that it might be duplicated incorrectly.</p> |
| <hr> |
| <a name="432"><h3>432. stringbuf::overflow() makes only one write position available</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#WP">WP</a> <b>Submitter:</b> Christian W Brock <b>Date:</b> 24 Sep 2003</p> |
| <p>27.7.1.3 par 8 says:</p> |
| <blockquote> |
| Notes: The function can make a write position available only if |
| ( mode & ios_base::out) != 0. To make a write position |
| available, the function reallocates (or initially allocates) an |
| array object with a sufficient number of elements to hold the |
| current array object (if any), plus one additional write position. |
| If ( mode & ios_base::in) != 0, the function alters the read end |
| pointer egptr() to point just past the new write position (as |
| does the write end pointer epptr()). |
| </blockquote> |
| |
| <p> |
| The sentences "plus one additional write position." and especially |
| "(as does the write end pointer epptr())" COULD by interpreted |
| (and is interpreted by at least my library vendor) as: |
| </p> |
| |
| <blockquote> |
| post-condition: epptr() == pptr()+1 |
| </blockquote> |
| |
| <p> |
| This WOULD force sputc() to call the virtual overflow() each time. |
| </p> |
| |
| <p>The proposed change also affects Defect Report 169.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>27.7.1.1/2 Change:</p> |
| |
| <blockquote> |
| 2- Notes: The function allocates no array object. |
| </blockquote> |
| |
| <p> |
| to: |
| </p> |
| |
| <blockquote> |
| 2- Postcondition: str() == "". |
| </blockquote> |
| |
| <p> |
| 27.7.1.1/3 Change: |
| </p> |
| |
| <blockquote> |
| <p> |
| -3- Effects: Constructs an object of class basic_stringbuf, |
| initializing the base class with basic_streambuf() |
| (lib.streambuf.cons), and initializing mode with which . Then copies |
| the content of str into the basic_stringbuf underlying character |
| sequence and initializes the input and output sequences according to |
| which. If which & ios_base::out is true, initializes the output |
| sequence with the underlying sequence. If which & ios_base::in is |
| true, initializes the input sequence with the underlying sequence. |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -3- Effects: Constructs an object of class basic_stringbuf, |
| initializing the base class with basic_streambuf() |
| (lib.streambuf.cons), and initializing mode with which. Then copies |
| the content of str into the basic_stringbuf underlying character |
| sequence. If which & ios_base::out is true, initializes the output |
| sequence such that pbase() points to the first underlying character, |
| epptr() points one past the last underlying character, and if (which & |
| ios_base::ate) is true, pptr() is set equal to |
| epptr() else pptr() is set equal to pbase(). If which & ios_base::in |
| is true, initializes the input sequence such that eback() and gptr() |
| point to the first underlying character and egptr() points one past |
| the last underlying character. |
| </p> |
| </blockquote> |
| |
| <p>27.7.1.2/1 Change:</p> |
| |
| <blockquote> |
| <p> |
| -1- Returns: A basic_string object whose content is equal to the |
| basic_stringbuf underlying character sequence. If the buffer is only |
| created in input mode, the underlying character sequence is equal to |
| the input sequence; otherwise, it is equal to the output sequence. In |
| case of an empty underlying character sequence, the function returns |
| basic_string<charT,traits,Allocator>(). |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -1- Returns: A basic_string object whose content is equal to the |
| basic_stringbuf underlying character sequence. If the basic_stringbuf |
| was created only in input mode, the resultant basic_string contains |
| the character sequence in the range [eback(), egptr()). If the |
| basic_stringbuf was created with (which & ios_base::out) being true |
| then the resultant basic_string contains the character sequence in the |
| range [pbase(), high_mark) where high_mark represents the position one |
| past the highest initialized character in the buffer. Characters can |
| be initialized either through writing to the stream, or by |
| constructing the basic_stringbuf with a basic_string, or by calling |
| the str(basic_string) member function. In the case of calling the |
| str(basic_string) member function, all characters initialized prior to |
| the call are now considered uninitialized (except for those |
| characters re-initialized by the new basic_string). Otherwise the |
| basic_stringbuf has been created in neither input nor output mode and |
| a zero length basic_string is returned. |
| </p> |
| </blockquote> |
| |
| <p> |
| 27.7.1.2/2 Change: |
| </p> |
| |
| <blockquote> |
| <p> |
| -2- Effects: If the basic_stringbuf's underlying character sequence is |
| not empty, deallocates it. Then copies the content of s into the |
| basic_stringbuf underlying character sequence and initializes the |
| input and output sequences according to the mode stored when creating |
| the basic_stringbuf object. If (mode&ios_base::out) is true, then |
| initializes the output sequence with the underlying sequence. If |
| (mode&ios_base::in) is true, then initializes the input sequence with |
| the underlying sequence. |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -2- Effects: Copies the content of s into the basic_stringbuf |
| underlying character sequence. If mode & ios_base::out is true, |
| initializes the output sequence such that pbase() points to the first |
| underlying character, epptr() points one past the last underlying |
| character, and if (mode & ios_base::ate) is true, |
| pptr() is set equal to epptr() else pptr() is set equal to pbase(). If |
| mode & ios_base::in is true, initializes the input sequence such that |
| eback() and gptr() point to the first underlying character and egptr() |
| points one past the last underlying character. |
| </p> |
| </blockquote> |
| |
| <p>Remove 27.2.1.2/3. (Same rationale as issue 238: incorrect and unnecessary.)</p> |
| |
| <p>27.7.1.3/1 Change:</p> |
| |
| <blockquote> |
| <p> |
| 1- Returns: If the input sequence has a read position available, |
| returns traits::to_int_type(*gptr()). Otherwise, returns |
| traits::eof(). |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| 1- Returns: If the input sequence has a read position available, |
| returns traits::to_int_type(*gptr()). Otherwise, returns |
| traits::eof(). Any character in the underlying buffer which has been |
| initialized is considered to be part of the input sequence. |
| </p> |
| </blockquote> |
| |
| <p>27.7.1.3/9 Change:</p> |
| |
| <blockquote> |
| <p> |
| -9- Notes: The function can make a write position available only if ( |
| mode & ios_base::out) != 0. To make a write position available, the |
| function reallocates (or initially allocates) an array object with a |
| sufficient number of elements to hold the current array object (if |
| any), plus one additional write position. If ( mode & ios_base::in) != |
| 0, the function alters the read end pointer egptr() to point just past |
| the new write position (as does the write end pointer epptr()). |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -9- The function can make a write position available only if ( mode & |
| ios_base::out) != 0. To make a write position available, the function |
| reallocates (or initially allocates) an array object with a sufficient |
| number of elements to hold the current array object (if any), plus one |
| additional write position. If ( mode & ios_base::in) != 0, the |
| function alters the read end pointer egptr() to point just past the |
| new write position. |
| </p> |
| </blockquote> |
| |
| <p>27.7.1.3/12 Change:</p> |
| |
| <blockquote> |
| <p> |
| -12- _ If (newoff + off) < 0, or (xend - xbeg) < (newoff + off), the |
| positioning operation fails. Otherwise, the function assigns xbeg + |
| newoff + off to the next pointer xnext . |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -12- _ If (newoff + off) < 0, or if (newoff + off) refers to an |
| uninitialized character (as defined in 27.7.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.stringbuf.members"> [lib.stringbuf.members]</a> |
| paragraph 1), the positioning operation fails. Otherwise, the function |
| assigns xbeg + newoff + off to the next pointer xnext . |
| </p> |
| </blockquote> |
| |
| <p><i>[post-Kona: Howard provided wording. At Kona the LWG agreed that |
| something along these lines was a good idea, but the original |
| proposed resolution didn't say enough about the effect of various |
| member functions on the underlying character sequences.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The current basic_stringbuf description is over-constrained in such |
| a way as to prohibit vendors from making this the high-performance |
| in-memory stream it was meant to be. The fundamental problem is that |
| the pointers: eback(), gptr(), egptr(), pbase(), pptr(), epptr() are |
| observable from a derived client, and the current description |
| restricts the range [pbase(), epptr()) from being grown geometrically. |
| This change allows, but does not require, geometric growth of this |
| range.</p> |
| |
| <p>Backwards compatibility issues: These changes will break code that |
| derives from basic_stringbuf, observes epptr(), and depends upon |
| [pbase(), epptr()) growing by one character on each call to overflow() |
| (i.e. test suites). Otherwise there are no backwards compatibility |
| issues.</p> |
| |
| <p>27.7.1.1/2: The non-normative note is non-binding, and if it were |
| binding, would be over specification. The recommended change focuses |
| on the important observable fact.</p> |
| |
| <p>27.7.1.1/3: This change does two things: 1. It describes exactly |
| what must happen in terms of the sequences. The terms "input |
| sequence" and "output sequence" are not well defined. 2. It |
| introduces a common extension: open with app or ate mode. I concur |
| with issue 238 that paragraph 4 is both wrong and unnecessary.</p> |
| |
| <p>27.7.1.2/1: This change is the crux of the efficiency issue. The |
| resultant basic_string is not dependent upon epptr(), and thus |
| implementors are free to grow the underlying buffer geometrically |
| during overflow() *and* place epptr() at the end of that buffer.</p> |
| |
| <p>27.7.1.2/2: Made consistent with the proposed 27.7.1.1/3.</p> |
| |
| <p>27.7.1.3/1: Clarifies that characters written to the stream beyond |
| the initially specified string are available for reading in an i/o |
| basic_streambuf.</p> |
| |
| <p>27.7.1.3/9: Made normative by removing "Notes:", and removed the |
| trailing parenthetical comment concerning epptr().</p> |
| |
| <p>27.7.1.3/12: Restricting the positioning to [xbeg, xend) is no |
| longer allowable since [pbase(), epptr()) may now contain |
| uninitialized characters. Positioning is only allowable over the |
| initialized range.</p> |
| <hr> |
| <a name="434"><h3>434. bitset::to_string() hard to use</h3></a><p><b>Section:</b> 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> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 15 Oct 2003</p> |
| <p> |
| It has been pointed out a number of times that the bitset to_string() member |
| function template is tedious to use since callers must explicitly specify the |
| entire template argument list (3 arguments). At least two implementations |
| provide a number of overloads of this template to make it easier to use. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In order to allow callers to specify no template arguments at all, just the |
| first one (charT), or the first 2 (charT and traits), in addition to all |
| three template arguments, add the following three overloads to both the |
| interface (declarations only) of the class template bitset as well as to |
| section 23.3.5.2, immediately after p34, the Returns clause of the existing |
| to_string() member function template:</p> |
| |
| <pre> template <class charT, class traits> |
| basic_string<charT, traits, allocator<charT> > |
| to_string () const; |
| |
| -34.1- Returns: to_string<charT, traits, allocator<charT> >(). |
| |
| template <class charT> |
| basic_string<charT, char_traits<charT>, allocator<charT> > |
| to_string () const; |
| |
| -34.2- Returns: to_string<charT, char_traits<charT>, allocator<charT> >(). |
| |
| basic_string<char, char_traits<char>, allocator<char> > |
| to_string () const; |
| |
| -34.3- Returns: to_string<char, char_traits<char>, allocator<char> >(). |
| </pre> |
| |
| <p><i>[Kona: the LWG agrees that this is an improvement over the |
| status quo. Dietmar thought about an alternative using a proxy |
| object but now believes that the proposed resolution above is the |
| right choice. |
| ]</i></p> |
| |
| <hr> |
| <a name="435"><h3>435. bug in DR 25</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 15 Oct 2003</p> |
| |
| <p> |
| It has been pointed out that the proposed resolution in DR 25 may not be |
| quite up to snuff: <br> |
| http://gcc.gnu.org/ml/libstdc++/2003-09/msg00147.html |
| http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#25<br> |
| </p> |
| |
| <p> |
| It looks like Petur is right. The complete corrected text is copied below. |
| I think we may have have been confused by the reference to 22.2.2.2.2 and |
| the subsequent description of `n' which actually talks about the second |
| argument to sputn(), not about the number of fill characters to pad with. |
| </p> |
| |
| <p> |
| So the question is: was the original text correct? If the intent was to |
| follow classic iostreams then it most likely wasn't, since setting width() |
| to less than the length of the string doesn't truncate it on output. This |
| is also the behavior of most implementations (except for SGI's standard |
| iostreams where the operator does truncate). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the text in 21.3.7.9, p4 from</p> |
| <blockquote> |
| If bool(k) is true, inserts characters as if by calling |
| os.rdbuf()->sputn(str.data(), n), padding as described in stage 3 |
| of lib.facet.num.put.virtuals, where n is the larger of os.width() |
| and str.size(); |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| If bool(k) is true, determines padding as described in |
| lib.facet.num.put.virtuals, and then inserts the resulting |
| sequence of characters <tt>seq</tt> as if by calling |
| <tt>os.rdbuf()->sputn(seq, n)</tt>, where <tt>n</tt> is the larger of |
| <tt>os.width()</tt> and <tt>str.size()</tt>; |
| </blockquote> |
| |
| <p><i>[Kona: it appears that neither the original wording, DR25, nor the |
| proposed resolution, is quite what we want. We want to say that |
| the string will be output, padded to os.width() if necessary. We |
| don't want to duplicate the padding rules in clause 22, because |
| they're complicated, but we need to be careful because they weren't |
| quite written with quite this case in mind. We need to say what |
| the character sequence is, and then defer to clause 22. Post-Kona: |
| Benjamin provided wording.]</i></p> |
| |
| <hr> |
| <a name="436"><h3>436. are cv-qualified facet types valid facets?</h3></a><p><b>Section:</b> 22.1.1.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.facet"> [lib.locale.facet]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 15 Oct 2003</p> |
| <p> |
| Is "const std::ctype<char>" a valid template argument to has_facet, use_facet, |
| and the locale template ctor? And if so, does it designate the same Facet as |
| the non-const "std::ctype<char>?" What about "volatile std::ctype<char>?" |
| Different implementations behave differently: some fail to compile, others |
| accept such types but behave inconsistently. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 22.1.1.1.2, p1 to read:</p> |
| |
| <p>Template parameters in this clause which are required to be facets |
| are those named Facet in declarations. A program that passes a type |
| that is not a facet, or a type that refers to volatile-qualified |
| facet, as an (explicit or deduced) template parameter to a locale |
| function expecting a facet, is ill-formed. A const-qualified facet is |
| a valid template argument to any locale function that expects a Facet |
| template parameter.</p> |
| |
| <p><i>[Kona: changed the last sentence from a footnote to normative |
| text.]</i></p> |
| |
| <hr> |
| <a name="438"><h3>438. Ambiguity in the "do the right thing" clause</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#DR">DR</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 20 Oct 2003</p> |
| |
| <p>Section 23.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.sequence.reqmts"> [lib.sequence.reqmts]</a>, paragraphs 9-11, fixed up the problem |
| noticed with statements like:</p> |
| <pre>vector<int> v(10, 1); |
| </pre> |
| |
| <p>The intent of the above statement was to construct with:</p> |
| <pre>vector(size_type, const value_type&); |
| </pre> |
| |
| <p>but early implementations failed to compile as they bound to:</p> |
| <pre>template <class InputIterator> |
| vector(InputIterator f, InputIterator l); |
| </pre> |
| <p>instead.</p> |
| |
| <p>Paragraphs 9-11 say that if InputIterator is an integral type, then the |
| member template constructor will have the same effect as:</p> |
| <pre>vector<static_cast<size_type>(f), static_cast<value_type>(l)); |
| </pre> |
| <p>(and similarly for the other member template functions of sequences).</p> |
| |
| <p>There is also a note that describes one implementation technique:</p> |
| <blockquote> |
| One way that sequence implementors can satisfy this requirement is to |
| specialize the member template for every integral type. |
| </blockquote> |
| |
| <p>This might look something like:</p> |
| <blockquote> |
| <pre>template <class T> |
| struct vector |
| { |
| typedef unsigned size_type; |
| |
| explicit vector(size_type) {} |
| vector(size_type, const T&) {} |
| |
| template <class I> |
| vector(I, I); |
| |
| // ... |
| }; |
| |
| template <class T> |
| template <class I> |
| vector<T>::vector(I, I) { ... } |
| |
| template <> |
| template <> |
| vector<int>::vector(int, int) { ... } |
| |
| template <> |
| template <> |
| vector<int>::vector(unsigned, unsigned) { ... } |
| |
| // ... |
| </pre> |
| </blockquote> |
| |
| <p>Label this solution 'A'.</p> |
| |
| <p>The standard also says:</p> |
| <blockquote> |
| Less cumbersome implementation techniques also exist. |
| </blockquote> |
| <p> |
| A popular technique is to not specialize as above, but instead catch |
| every call with the member template, detect the type of InputIterator, |
| and then redirect to the correct logic. Something like: |
| </p> |
| <blockquote> |
| <pre>template <class T> |
| template <class I> |
| vector<T>::vector(I f, I l) |
| { |
| choose_init(f, l, int2type<is_integral<I>::value>()); |
| } |
| |
| template <class T> |
| template <class I> |
| vector<T>::choose_init(I f, I l, int2type<false>) |
| { |
| // construct with iterators |
| } |
| |
| template <class T> |
| template <class I> |
| vector<T>::choose_init(I f, I l, int2type<true>) |
| { |
| size_type sz = static_cast<size_type>(f); |
| value_type v = static_cast<value_type>(l); |
| // construct with sz,v |
| } |
| </pre> |
| </blockquote> |
| |
| <p>Label this solution 'B'.</p> |
| |
| <p>Both of these solutions solve the case the standard specifically |
| mentions:</p> |
| <pre>vector<int> v(10, 1); // ok, vector size 10, initialized to 1 |
| </pre> |
| |
| <p> |
| However, (and here is the problem), the two solutions have different |
| behavior in some cases where the value_type of the sequence is not an |
| integral type. For example consider: |
| </p> |
| <blockquote><pre> pair<char, char> p('a', 'b'); |
| vector<vector<pair<char, char> > > d('a', 'b'); |
| </pre></blockquote> |
| <p> |
| The second line of this snippet is likely an error. Solution A catches |
| the error and refuses to compile. The reason is that there is no |
| specialization of the member template constructor that looks like: |
| </p> |
| <pre>template <> |
| template <> |
| vector<vector<pair<char, char> > >::vector(char, char) { ... } |
| </pre> |
| |
| <p> |
| So the expression binds to the unspecialized member template |
| constructor, and then fails (compile time) because char is not an |
| InputIterator. |
| </p> |
| |
| <p> |
| Solution B compiles the above example though. 'a' is casted to an |
| unsigned integral type and used to size the outer vector. 'b' is |
| static casted to the inner vector using it's explicit constructor: |
| </p> |
| |
| <pre>explicit vector(size_type n); |
| </pre> |
| |
| <p> |
| and so you end up with a static_cast<size_type>('a') by |
| static_cast<size_type>('b') matrix. |
| </p> |
| |
| <p> |
| It is certainly possible that this is what the coder intended. But the |
| explicit qualifier on the inner vector has been thwarted at any rate. |
| </p> |
| |
| <p> |
| The standard is not clear whether the expression: |
| </p> |
| |
| <pre> vector<vector<pair<char, char> > > d('a', 'b'); |
| </pre> |
| |
| <p> |
| (and similar expressions) are: |
| </p> |
| |
| <ol> |
| <li> undefined behavior.</li> |
| <li> illegal and must be rejected.</li> |
| <li> legal and must be accepted.</li> |
| </ol> |
| |
| <p>My preference is listed in the order presented.</p> |
| |
| <p>There are still other techniques for implementing the requirements of |
| paragraphs 9-11, namely the "restricted template technique" (e.g. |
| enable_if). This technique is the most compact and easy way of coding |
| the requirements, and has the behavior of #2 (rejects the above |
| expression). |
| </p> |
| |
| <p> |
| Choosing 1 would allow all implementation techniques I'm aware of. |
| Choosing 2 would allow only solution 'A' and the enable_if technique. |
| Choosing 3 would allow only solution 'B'. |
| </p> |
| |
| <p> |
| Possible wording for a future standard if we wanted to actively reject |
| the expression above would be to change "static_cast" in paragraphs |
| 9-11 to "implicit_cast" where that is defined by: |
| </p> |
| |
| <blockquote> |
| <pre>template <class T, class U> |
| inline |
| T implicit_cast(const U& u) |
| { |
| return u; |
| } |
| </pre> |
| </blockquote> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| Replace 23.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.sequence.reqmts"> [lib.sequence.reqmts]</a> paragraphs 9 - 11 with: |
| |
| <p>For every sequence defined in this clause and in clause lib.strings:</p> |
| |
| <ul> |
| <li> |
| <p>If the constructor</p> |
| <pre> template <class InputIterator> |
| X(InputIterator f, InputIterator l, |
| const allocator_type& a = allocator_type()) |
| </pre> |
| <p>is called with a type InputIterator that does not qualify as |
| an input iterator, then the constructor will behave as if the |
| overloaded constructor:</p> |
| <pre> X(size_type, const value_type& = value_type(), |
| const allocator_type& = allocator_type()) |
| </pre> |
| <p>were called instead, with the arguments static_cast<size_type>(f), l and a, respectively.</p> |
| </li> |
| |
| <li> |
| <p>If the member functions of the forms:</p> |
| <pre> template <class InputIterator> // such as insert() |
| rt fx1(iterator p, InputIterator f, InputIterator l); |
| |
| template <class InputIterator> // such as append(), assign() |
| rt fx2(InputIterator f, InputIterator l); |
| |
| template <class InputIterator> // such as replace() |
| rt fx3(iterator i1, iterator i2, InputIterator f, InputIterator l); |
| </pre> |
| <p>are called with a type InputIterator that does not qualify as |
| an input iterator, then these functions will behave as if the |
| overloaded member functions:</p> |
| <pre> rt fx1(iterator, size_type, const value_type&); |
| |
| rt fx2(size_type, const value_type&); |
| |
| rt fx3(iterator, iterator, size_type, const value_type&); |
| </pre> |
| <p>were called instead, with the same arguments.</p> |
| </li> |
| </ul> |
| |
| <p>In the previous paragraph the alternative binding will fail if f |
| is not implicitly convertible to X::size_type or if l is not implicitly |
| convertible to X::value_type.</p> |
| |
| <p> |
| The extent to which an implementation determines that a type cannot be |
| an input iterator is unspecified, except that as a minimum integral |
| types shall not qualify as input iterators. |
| </p> |
| |
| |
| |
| <p><i>[ |
| Kona: agreed that the current standard requires <tt>v('a', 'b')</tt> |
| to be accepted, and also agreed that this is surprising behavior. The |
| LWG considered several options, including something like |
| implicit_cast, which doesn't appear to be quite what we want. We |
| considered Howards three options: allow acceptance or rejection, |
| require rejection as a compile time error, and require acceptance. By |
| straw poll (1-6-1), we chose to require a compile time error. |
| Post-Kona: Howard provided wording. |
| ]</i></p> |
| |
| <p><i>[ |
| Sydney: The LWG agreed with this general direction, but there was some |
| discomfort with the wording in the original proposed resolution. |
| Howard submitted new wording, and we will review this again in |
| Redmond. |
| ]</i></p> |
| |
| <p><i>[Redmond: one very small change in wording: the first argument |
| is cast to size_t. This fixes the problem of something like |
| <tt>vector<vector<int> >(5, 5)</tt>, where int is not |
| implicitly convertible to the value type.]</i></p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The proposed resolution fixes:</p> |
| |
| <pre> vector<int> v(10, 1); |
| </pre> |
| |
| <p> |
| since as integral types 10 and 1 must be disqualified as input |
| iterators and therefore the (size,value) constructor is called (as |
| if).</p> |
| |
| <p>The proposed resolution breaks:</p> |
| |
| <pre> vector<vector<T> > v(10, 1); |
| </pre> |
| |
| <p> |
| because the integral type 1 is not *implicitly* convertible to |
| vector<T>. The wording above requires a diagnostic.</p> |
| |
| <p> |
| The proposed resolution leaves the behavior of the following code |
| unspecified. |
| </p> |
| |
| <pre> struct A |
| { |
| operator int () const {return 10;} |
| }; |
| |
| struct B |
| { |
| B(A) {} |
| }; |
| |
| vector<B> v(A(), A()); |
| </pre> |
| |
| <p> |
| The implementation may or may not detect that A is not an input |
| iterator and employee the (size,value) constructor. Note though that |
| in the above example if the B(A) constructor is qualified explicit, |
| then the implementation must reject the constructor as A is no longer |
| implicitly convertible to B. |
| </p> |
| <hr> |
| <a name="441"><h3>441. Is fpos::state const?</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#WP">WP</a> <b>Submitter:</b> Vincent Leloup <b>Date:</b> 17 Nov 2003</p> |
| <p> |
| In section 27.4.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fpos.members"> [lib.fpos.members]</a> fpos<stateT>::state() is declared |
| non const, but in section 27.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fpos"> [lib.fpos]</a> it is declared const. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In section 27.4.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fpos.members"> [lib.fpos.members]</a>, change the declaration of |
| <tt>fpos<stateT>::state()</tt> to const. |
| </p> |
| <hr> |
| <a name="442"><h3>442. sentry::operator bool() inconsistent signature</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#WP">WP</a> <b>Submitter:</b> Vincent Leloup <b>Date:</b> 18 Nov 2003</p> |
| <p> |
| In section 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> paragraph 4, in description part |
| basic_ostream<charT, traits>::sentry::operator bool() is declared |
| as non const, but in section 27.6.2.3, in synopsis it is declared |
| const. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In section 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> paragraph 4, change the declaration |
| of <tt>sentry::operator bool()</tt> to const. |
| </p> |
| <hr> |
| <a name="443"><h3>443. filebuf::close() inconsistent use of EOF</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#WP">WP</a> <b>Submitter:</b> Vincent Leloup <b>Date:</b> 20 Nov 2003</p> |
| <p> |
| In section 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> par6, in effects description of |
| basic_filebuf<charT, traits>::close(), overflow(EOF) is used twice; |
| should be overflow(traits::eof()). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change overflow(EOF) to overflow(traits::eof()). |
| </p> |
| <hr> |
| <a name="444"><h3>444. Bad use of casts in fstream</h3></a><p><b>Section:</b> 27.8.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstreams"> [lib.fstreams]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Vincent Leloup <b>Date:</b> 20 Nov 2003</p> |
| <p> |
| 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> p1, 27.8.1.10 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ofstream.members"> [lib.ofstream.members]</a> p1, 27.8.1.13 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstream.members"> [lib.fstream.members]</a> p1 seems have same problem as exposed in LWG issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#252">252</a>. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Sydney: Genuine defect. 27.8.1.13 needs a cast to cast away |
| constness. The other two places are stylistic: we could change the |
| C-style casts to const_cast. Post-Sydney: Howard provided wording. |
| ]</i></p> |
| |
| <p>Change 27.8.1.7/1 from:</p> |
| <blockquote> |
| Returns: (basic_filebuf<charT,traits>*)&sb. |
| </blockquote> |
| |
| <p>to:</p> |
| <blockquote> |
| Returns: const_cast<basic_filebuf<charT,traits>*>(&sb). |
| </blockquote> |
| |
| <p>Change 27.8.1.10/1 from:</p> |
| <blockquote> |
| Returns: (basic_filebuf<charT,traits>*)&sb. |
| </blockquote> |
| |
| <p>to:</p> |
| <blockquote> |
| Returns: const_cast<basic_filebuf<charT,traits>*>(&sb). |
| </blockquote> |
| |
| <p>Change 27.8.1.13/1 from:</p> |
| <blockquote> |
| Returns: &sb. |
| </blockquote> |
| |
| <p>to:</p> |
| <blockquote> |
| Returns: const_cast<basic_filebuf<charT,traits>*>(&sb). |
| </blockquote> |
| |
| |
| |
| <hr> |
| <a name="445"><h3>445. iterator_traits::reference unspecified for some iterator categories</h3></a><p><b>Section:</b> 24.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.traits"> [lib.iterator.traits]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 9 Dec 2003</p> |
| <p> |
| The standard places no restrictions at all on the reference type |
| of input, output, or forward iterators (for forward iterators it |
| only specifies that *x must be value_type& and doesn't mention |
| the reference type). Bidirectional iterators' reference type is |
| restricted only by implication, since the base iterator's |
| reference type is used as the return type of reverse_iterator's |
| operator*, which must be T& in order to be a conforming forward |
| iterator. |
| </p> |
| |
| <p> |
| Here's what I think we ought to be able to expect from an input |
| or forward iterator's reference type R, where a is an iterator |
| and V is its value_type |
| </p> |
| |
| <ul> |
| <li> |
| *a is convertible to R |
| </li> |
| |
| <li> |
| R is convertible to V |
| </li> |
| |
| <li> |
| static_cast<V>(static_cast<R>(*a)) is equivalent to |
| static_cast<V>(*a) |
| </li> |
| </ul> |
| |
| <p>A mutable forward iterator ought to satisfy, for x of type V:</p> |
| <li> |
| { R r = *a; r = x; } is equivalent to *a = x; |
| </li> |
| |
| <p> |
| I think these requirements capture existing container iterators |
| (including vector<bool>'s), but render istream_iterator invalid; |
| its reference type would have to be changed to a constant |
| reference. |
| </p> |
| |
| |
| <p> |
| (Jeremy Siek) During the discussion in Sydney, it was felt that a |
| simpler long term solution for this was needed. The solution proposed |
| was to require <tt>reference</tt> to be the same type as <tt>*a</tt> |
| and <tt>pointer</tt> to be the same type as <tt>a-></tt>. Most |
| iterators in the Standard Library already meet this requirement. Some |
| iterators are output iterators, and do not need to meet the |
| requirement, and others are only specified through the general |
| iterator requirements (which will change with this resolution). The |
| sole case where there is an explicit definition of the reference type |
| that will need to change is <tt>istreambuf_iterator</tt> which returns |
| <tt>charT</tt> from <tt>operator*</tt> but has a reference type of |
| <tt>charT&</tt>. We propose changing the reference type of |
| <tt>istreambuf_iterator</tt> to <tt>charT</tt>. |
| </p> |
| |
| <p>The other option for resolving the issue with <tt>pointer</tt>, |
| mentioned in the note below, is to remove <tt>pointer</tt> |
| altogether. I prefer placing requirements on <tt>pointer</tt> to |
| removing it for two reasons. First, <tt>pointer</tt> will become |
| useful for implementing iterator adaptors and in particular, |
| <tt>reverse_iterator</tt> will become more well defined. Second, |
| removing <tt>pointer</tt> is a rather drastic and publicly-visible |
| action to take.</p> |
| |
| <p>The proposed resolution technically enlarges the requirements for |
| iterators, which means there are existing iterators (such as |
| <tt>istreambuf_iterator</tt>, and potentially some programmer-defined |
| iterators) that will no longer meet the requirements. Will this break |
| existing code? The scenario in which it would is if an algorithm |
| implementation (say in the Standard Library) is changed to rely on |
| <tt>iterator_traits::reference</tt>, and then is used with one of the |
| iterators that do not have an appropriately defined |
| <tt>iterator_traits::reference</tt>. |
| </p> |
| |
| |
| <p>The proposed resolution makes one other subtle change. Previously, |
| it was required that output iterators have a <tt>difference_type</tt> |
| and <tt>value_type</tt> of <tt>void</tt>, which means that a forward |
| iterator could not be an output iterator. This is clearly a mistake, |
| so I've changed the wording to say that those types may be |
| <tt>void</tt>. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>In 24.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.traits"> [lib.iterator.traits]</a>, after:</p> |
| |
| <blockquote> |
| be defined as the iterator's difference type, value type and iterator |
| category, respectively. |
| </blockquote> |
| |
| <p>add</p> |
| |
| <blockquote> |
| In addition, the types |
| <pre>iterator_traits<Iterator>::reference |
| iterator_traits<Iterator>::pointer |
| </pre> |
| must be defined as the iterator's reference and pointer types, that |
| is, the same type as the type of <tt>*a</tt> and <tt>a-></tt>, |
| respectively. |
| </blockquote> |
| |
| <p>In 24.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.iterator.traits"> [lib.iterator.traits]</a>, change:</p> |
| |
| <blockquote> |
| In the case of an output iterator, the types |
| <pre>iterator_traits<Iterator>::difference_type |
| iterator_traits<Iterator>::value_type |
| </pre> |
| are both defined as <tt>void</tt>. |
| </blockquote> |
| |
| <p>to:</p> |
| <blockquote> |
| In the case of an output iterator, the types |
| <pre>iterator_traits<Iterator>::difference_type |
| iterator_traits<Iterator>::value_type |
| iterator_traits<Iterator>::reference |
| iterator_traits<Iterator>::pointer |
| </pre> |
| may be defined as <tt>void</tt>. |
| </blockquote> |
| |
| <p>In 24.5.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.istreambuf.iterator"> [lib.istreambuf.iterator]</a>, change:</p> |
| <blockquote> |
| <pre>typename traits::off_type, charT*, charT&> |
| </pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <pre>typename traits::off_type, charT*, charT> |
| </pre> |
| </blockquote> |
| |
| <p><i>[ |
| Redmond: there was concern in Sydney that this might not be the only place |
| where things were underspecified and needed to be changed. Jeremy |
| reviewed iterators in the standard and confirmed that nothing else |
| needed to be changed. |
| ]</i></p> |
| |
| <hr> |
| <a name="448"><h3>448. Random Access Iterators over abstract classes</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#WP">WP</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 7 Jan 2004</p> |
| <p> |
| Table 76, the random access iterator requirement table, says that the |
| return type of a[n] must be "convertible to T". When an iterator's |
| value_type T is an abstract class, nothing is convertible to T. |
| Surely this isn't an intended restriction? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the return type to "convertible to T const&". |
| </p> |
| <hr> |
| <a name="449"><h3>449. Library Issue 306 Goes Too Far</h3></a><p><b>Section:</b> 18.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.support.types"> [lib.support.types]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 15 Jan 2004</p> |
| <p>Original text:</p> |
| <blockquote> |
| The macro offsetof accepts a restricted set of type arguments in this |
| International Standard. type shall be a POD structure or a POD union |
| (clause 9). The result of applying the offsetof macro to a field that |
| is a static data member or a function member is undefined." |
| </blockquote> |
| |
| <p>Revised text:</p> |
| <blockquote> |
| "If type is not a POD structure or a POD union the results are undefined." |
| </blockquote> |
| |
| <p> |
| Looks to me like the revised text should have replaced only the second |
| sentence. It doesn't make sense standing alone. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 18.1, paragraph 5, to:</p> |
| |
| <blockquote> |
| The macro offsetof accepts a restricted set of type arguments in this |
| International Standard. If type is not a POD structure or a POD union |
| the results are undefined. The result of applying the offsetof macro |
| to a field that is a static data member or a function member is |
| undefined." |
| </blockquote> |
| <hr> |
| <a name="453"><h3>453. basic_stringbuf::seekoff need not always fail for an empty stream</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#DR">DR</a> <b>Submitter:</b> Bill Plauger <b>Date:</b> 30 Jan 2004</p> |
| <pre> pos_type basic_stringbuf::seekoff(off_type, ios_base::seekdir, |
| ios_base::openmode); |
| </pre> |
| <p> |
| is obliged to fail if nothing has been inserted into the stream. This |
| is unnecessary and undesirable. It should be permissible to seek to |
| an effective offset of zero.</p> |
| |
| <p><i>[ |
| Sydney: Agreed that this is an annoying problem: seeking to zero should be |
| legal. Bill will provide wording. |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the sentence from:</p> |
| <blockquote> |
| For a sequence to be positioned, if its next pointer (either |
| gptr() or pptr()) is a null pointer, the positioning operation |
| fails. |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| For a sequence to be positioned, if its next pointer (either |
| gptr() or pptr()) is a null pointer and the new offset newoff |
| is nonzero, the positioning operation fails. |
| </blockquote> |
| <hr> |
| <a name="455"><h3>455. cerr::tie() and wcerr::tie() are overspecified</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#DR">DR</a> <b>Submitter:</b> Bill Plauger <b>Date:</b> 30 Jan 2004</p> |
| <p> |
| Both cerr::tie() and wcerr::tie() are obliged to be null at program |
| startup. This is overspecification and overkill. It is both traditional |
| and useful to tie cerr to cout, to ensure that standard output is drained |
| whenever an error message is written. This behavior should at least be |
| permitted if not required. Same for wcerr::tie(). |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add to the description of cerr:</p> |
| <blockquote> |
| After the object cerr is initialized, cerr.tie() returns &cout. |
| Its state is otherwise the same as required for basic_ios<char>::init |
| (lib.basic.ios.cons). |
| </blockquote> |
| |
| <p>Add to the description of wcerr:</p> |
| |
| <blockquote> |
| After the object wcerr is initialized, wcerr.tie() returns &wcout. |
| Its state is otherwise the same as required for basic_ios<wchar_t>::init |
| (lib.basic.ios.cons). |
| </blockquote> |
| |
| <p><i>[Sydney: straw poll (3-1): we should <i>require</i>, not just |
| permit, cout and cerr to be tied on startup. Pre-Redmond: Bill will |
| provide wording.]</i></p> |
| <hr> |
| <a name="457"><h3>457. bitset constructor: incorrect number of initialized bits</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#DR">DR</a> <b>Submitter:</b> Dag Henriksson <b>Date:</b> 30 Jan 2004</p> |
| <p> |
| The constructor from unsigned long says it initializes "the first M |
| bit positions to the corresponding bit values in val. M is the smaller |
| of N and the value CHAR_BIT * sizeof(unsigned long)." |
| </p> |
| |
| <p> |
| Object-representation vs. value-representation strikes again. CHAR_BIT * |
| sizeof (unsigned long) does not give us the number of bits an unsigned long |
| uses to hold the value. Thus, the first M bit position above is not |
| guaranteed to have any corresponding bit values in val. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 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> paragraph 2, change "M is the smaller of |
| N and the value CHAR_BIT * sizeof (unsigned long). (249)" to |
| "<tt>M</tt> is the smaller of <tt>N</tt> and the number of bits in |
| the value representation (section 3.9 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/basic.html#basic.types"> [basic.types]</a>) of <tt>unsigned |
| long</tt>." |
| </p> |
| <hr> |
| <a name="460"><h3>460. Default modes missing from basic_fstream member specifications</h3></a><p><b>Section:</b> 27.8.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstreams"> [lib.fstreams]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Ben Hutchings <b>Date:</b> 1 Apr 2004</p> |
| <p> |
| The second parameters of the non-default constructor and of the open |
| member function for basic_fstream, named "mode", are optional |
| according to the class declaration in 27.8.1.11 [lib.fstream]. The |
| specifications of these members in 27.8.1.12 [lib.fstream.cons] and |
| 27.8.1.13 lib.fstream.members] disagree with this, though the |
| constructor declaration has the "explicit" function-specifier implying |
| that it is intended to be callable with one argument. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.8.1.12 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstream.cons"> [lib.fstream.cons]</a>, change</p> |
| <pre> explicit basic_fstream(const char* s, ios_base::openmode mode); |
| </pre> |
| <p>to</p> |
| <pre> explicit basic_fstream(const char* s, |
| ios_base::openmode mode = ios_base::in|ios_base::out); |
| </pre> |
| <p>In 27.8.1.13 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.fstream.members"> [lib.fstream.members]</a>, change</p> |
| <pre> void open(const char*s, ios_base::openmode mode); |
| </pre> |
| <p>to</p> |
| void open(const char*s, |
| ios_base::openmode mode = ios_base::in|ios_base::out); |
| <hr> |
| <a name="461"><h3>461. time_get hard or impossible to implement</h3></a><p><b>Section:</b> 22.2.5.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.locale.time.get.virtuals"> [lib.locale.time.get.virtuals]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Bill Plauger <b>Date:</b> 23 Mar 2004</p> |
| <p> |
| Template time_get currently contains difficult, if not impossible, |
| requirements for do_date_order, do_get_time, and do_get_date. All require |
| the implementation to scan a field generated by the %x or %X conversion |
| specifier in strftime. Yes, do_date_order can always return no_order, but |
| that doesn't help the other functions. The problem is that %x can be |
| nearly anything, and it can vary widely with locales. It's horribly |
| onerous to have to parse "third sunday after Michaelmas in the year of |
| our Lord two thousand and three," but that's what we currently ask of |
| do_get_date. More practically, it leads some people to think that if |
| %x produces 10.2.04, we should know to look for dots as separators. Still |
| not easy. |
| </p> |
| |
| <p> |
| Note that this is the <i>opposite</i> effect from the intent stated in the |
| footnote earlier in this subclause: |
| </p> |
| |
| <blockquote> |
| "In other words, user confirmation is required for reliable parsing of |
| user-entered dates and times, but machine-generated formats can be |
| parsed reliably. This allows parsers to be aggressive about interpreting |
| user variations on standard formats." |
| </blockquote> |
| |
| <p> |
| We should give both implementers and users an easier and more reliable |
| alternative: provide a (short) list of alternative delimiters and say |
| what the default date order is for no_order. For backward compatibility, |
| and maximum latitude, we can permit an implementation to parse whatever |
| %x or %X generates, but we shouldn't require it. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><b>In the description:</b></p> |
| <pre>iter_type do_get_time(iter_type s, iter_type end, ios_base& str, |
| ios_base::iostate& err, tm* t) const; |
| </pre> |
| |
| <p> |
| 2 Effects: Reads characters starting at suntil it has extracted those |
| struct tm members, and remaining format characters, used by |
| time_put<>::put to produce the format specified by 'X', or until it |
| encounters an error or end of sequence. |
| </p> |
| |
| <p><b>change:</b> 'X'</p> |
| |
| <p><b>to:</b> "%H:%M:%S"</p> |
| |
| |
| <p>Change</p> |
| <pre>iter_type do_get_date(iter_type s, iter_type end, ios_base& str, |
| ios_base::iostate& err, tm* t) const; |
| |
| 4 Effects: Reads characters starting at s until it has extracted those |
| struct tm members, and remaining format characters, used by |
| time_put<>::put to produce the format specified by 'x', or until it |
| encounters an error. |
| </pre> |
| |
| <p>to</p> |
| iter_type do_get_date(iter_type s, iter_type end, ios_base& str, |
| ios_base::iostate& err, tm* t) const; |
| |
| 4 Effects: Reads characters starting at s until it has extracted those |
| struct tm members, and remaining format characters, used by |
| time_put<>::put to produce one of the following formats, or until it |
| encounters an error. The format depends on the value returned by |
| date_order() as follows: |
| |
| date_order() format |
| |
| no_order "%m/%d/%y" |
| dmy "%d/%m/%y" |
| mdy "%m/%d/%y" |
| ymd "%y/%m/%d" |
| ydm "%y/%d/%m" |
| |
| An implementation may also accept additional implementation-defined formats. |
| <pre></pre> |
| |
| <p><i>[Redmond: agreed that this is a real problem. The solution is |
| probably to match C99's parsing rules. Bill provided wording. |
| ]</i></p> |
| |
| <hr> |
| <a name="464"><h3>464. Suggestion for new member functions in standard containers</h3></a><p><b>Section:</b> 23.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.adaptors"> [lib.container.adaptors]</a>, 23.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map"> [lib.map]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Thorsten Ottosen <b>Date:</b> 12 May 2004</p> |
| |
| <p>To add slightly more convenience to vector<T> and map<Key,T> we should consider to add</p> |
| <ol> |
| <li> add vector<T>::data() member (const and non-const version) |
| semantics: if( empty() ) return 0; else return buffer_;</li> |
| <li> add map<Key,T>::at( const Key& k ) member (const and non-const version) |
| <i>semantics</i>: iterator i = find( k ); if( i != end() ) return *i; else throw range_error();</li> |
| </ol> |
| |
| <p>Rationale:</p> |
| |
| <ul> |
| <li>To obtain a pointer to the vector's buffer, one must use either |
| operator[]() (which can give undefined behavior for empty vectors) or |
| at() (which will then throw if the vector is empty). </li> |
| <li>tr1::array<T,sz> already has a data() member</li> |
| <li>e cannot use operator[]() when T is not DefaultDonstructible</li> |
| <li>Neither when the map is const.</li> |
| <li>when we want to make sure we don't add an element accidently</li> |
| <li>when it should be considered an error if a key is not in the map</li> |
| </ul> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.adaptors"> [lib.container.adaptors]</a>, add the following to the <tt>vector</tt> |
| synopsis after "element access" and before "modifiers":</p> |
| <pre> // <i>[lib.vector.data] data access</i> |
| pointer data(); |
| const_pointer data() const; |
| </pre> |
| |
| <p>Add a new subsection of 23.2.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.container.adaptors"> [lib.container.adaptors]</a>:</p> |
| <blockquote> |
| <p>23.2.4.x <tt>vector</tt> data access</p> |
| <pre> pointer data(); |
| const_pointer data() const; |
| </pre> |
| <p><b>Returns:</b> A pointer such that [data(), data() + size()) is a valid |
| range. For a non-empty vector, data() == &front().</p> |
| <p><b>Complexity:</b> Constant time.</p> |
| <p><b>Throws:</b> Nothing.</p> |
| </blockquote> |
| |
| <p>In 23.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map"> [lib.map]</a>, add the following to the <tt>map</tt> |
| synopsis immediately after the line for operator[]:</p> |
| <pre> T& at(const key_type& x); |
| const T& at(const key_type& x) const; |
| </pre> |
| |
| <p>Add the following to 23.3.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.map.access"> [lib.map.access]</a>:</p> |
| <blockquote> |
| <pre> T& at(const key_type& x); |
| const T& at(const key_type& x) const; |
| </pre> |
| |
| <p><b>Returns:</b> A reference to the element whose key is equivalent |
| to x, if such an element is present in the map.</p> |
| <p><b>Throws:</b> <tt>out_of_range</tt> if no such element is present.</p> |
| |
| </blockquote> |
| |
| <p><b>Rationale:</b></p> |
| <p>Neither of these additions provides any new functionality but the |
| LWG agreed that they are convenient, especially for novices. The |
| exception type chosen for <tt>at</tt>, <tt>std::out_of_range</tt>, |
| was chosen to match <tt>vector::at</tt>.</p> |
| <hr> |
| <a name="465"><h3>465. Contents of <ciso646></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#WP">WP</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 3 Jun 2004</p> |
| <p>C header <iso646.h> defines macros for some operators, such as |
| not_eq for !=.</p> |
| |
| <p>Section 17.4.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.headers"> [lib.headers]</a> "Headers" says that except as noted in |
| clauses 18 through 27, the <cname> C++ header contents are the same |
| as the C header <name.h>. In particular, table 12 lists |
| <ciso646> as a C++ header.</p> |
| |
| <p>I don't find any other mention of <ciso646>, or any mention of |
| <iso646.h>, in clauses 17 thorough 27. That implies that the |
| contents of <ciso646> are the same as C header <iso646.h>.</p> |
| |
| <p>Annex C (informative, not normative) in [diff.header.iso646.h] C.2.2.2 |
| "Header <iso646.h>" says that the alternative tokens are not |
| defined as macros in <ciso646>, but does not mention the contents |
| of <iso646.h>.</p> |
| |
| <p>I don't find any normative text to support C.2.2.2.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to section 17.4.1.2 Headers [lib.headers] a new paragraph after |
| paragraph 6 (the one about functions must be functions):</p> |
| |
| <blockquote> |
| <p>Identifiers that are keywords or operators in C++ shall not be defined |
| as macros in C++ standard library headers. |
| [Footnote:In particular, including the standard header <iso646.h> |
| or <ciso646> has no effect. </p> |
| </blockquote> |
| |
| <p><i>[post-Redmond: Steve provided wording.]</i></p> |
| |
| <hr> |
| <a name="467"><h3>467. char_traits::lt(), compare(), and memcmp()</h3></a><p><b>Section:</b> 21.1.3.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.char.traits.specializations.char"> [lib.char.traits.specializations.char]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 Jun 2004</p> |
| |
| <p> |
| Table 37 describes the requirements on Traits::compare() in terms of |
| those on Traits::lt(). 21.1.3.1, p6 requires char_traits<char>::lt() |
| to yield the same result as operator<(char, char). |
| </p> |
| |
| <p> |
| Most, if not all, implementations of char_traits<char>::compare() |
| call memcmp() for efficiency. However, the C standard requires both |
| memcmp() and strcmp() to interpret characters under comparison as |
| unsigned, regardless of the signedness of char. As a result, all |
| these char_traits implementations fail to meet the requirement |
| imposed by Table 37 on compare() when char is signed. |
| </p> |
| |
| |
| <p>Read email thread starting with c++std-lib-13499 for more. </p> |
| <p><b>Proposed resolution:</b></p> |
| |
| |
| <p>Change 21.1.3.1, p6 from</p> |
| <blockquote> |
| The two-argument members assign, eq, and lt are defined identically |
| to the built-in operators =, ==, and < respectively. |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| The two-argument member assign is defined identically to |
| the built-in operator =. The two |
| argument members eq and lt are defined identically to |
| the built-in operators == and < for type unsigned char. |
| </blockquote> |
| |
| <p><i>[Redmond: The LWG agreed with this general direction, but we |
| also need to change <tt>eq</tt> to be consistent with this change. |
| Post-Redmond: Martin provided wording.]</i></p> |
| |
| <hr> |
| <a name="468"><h3>468. unexpected consequences of ios_base::operator void*()</h3></a><p><b>Section:</b> 27.4.4.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.iostate.flags"> [lib.iostate.flags]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 Jun 2004</p> |
| |
| <p>The program below is required to compile but when run it typically |
| produces unexpected results due to the user-defined conversion from |
| std::cout or any object derived from basic_ios to void*. |
| </p> |
| |
| <pre> #include <cassert> |
| #include <iostream> |
| |
| int main () |
| { |
| assert (std::cin.tie () == std::cout); |
| // calls std::cout.ios::operator void*() |
| } |
| </pre> |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Replace std::basic_ios<charT, traits>::operator void*() with another |
| conversion operator to some unspecified type that is guaranteed not |
| to be convertible to any other type except for bool (a pointer-to-member |
| might be one such suitable type). In addition, make it clear that the |
| pointer type need not be a pointer to a complete type and when non-null, |
| the value need not be valid. |
| </p> |
| |
| <p>Specifically, change in [lib.ios] the signature of</p> |
| <pre> operator void*() const; |
| </pre> |
| <p>to</p> |
| <pre> operator unspecified-bool-type() const; |
| </pre> |
| <p>and change [lib.iostate.flags], p1 from</p> |
| <pre> operator void*() const; |
| </pre> |
| <p>to</p> |
| <pre>operator unspecified-bool-type() const; |
| |
| -1- Returns: if fail() then a value that will evaluate false in a |
| boolean context; otherwise a value that will evaluate true in a |
| boolean context. The value type returned shall not be |
| convertible to int. |
| |
| -2- [Note: This conversion can be used in contexts where a bool |
| is expected (e.g., an if condition); however, implicit |
| conversions (e.g., to int) that can occur with bool are not |
| allowed, eliminating some sources of user error. One possible |
| implementation choice for this type is pointer-to-member. - end |
| note] |
| </pre> |
| |
| <p><i>[Redmond: 5-4 straw poll in favor of doing this.]</i></p> |
| <p><i>[Lillehammer: Doug provided revised wording for |
| "unspecified-bool-type".]</i></p> |
| |
| <hr> |
| <a name="469"><h3>469. vector<bool> ill-formed relational operators</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#DR">DR</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 28 Jun 2004</p> |
| |
| <p> |
| The overloads of relational operators for vector<bool> specified |
| in [lib.vector.bool] are redundant (they are semantically identical |
| to those provided for the vector primary template) and may even be |
| diagnosed as ill-formed (refer to Daveed Vandevoorde's explanation |
| in c++std-lib-13647). |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove all overloads of overloads of relational operators for |
| vector<bool> from [lib.vector.bool]. |
| </p> |
| <hr> |
| <a name="474"><h3>474. confusing Footnote 297</h3></a><p><b>Section:</b> 27.6.2.5.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 1 Jul 2004</p> |
| |
| <p> |
| I think Footnote 297 is confused. The paragraph it applies to seems |
| quite clear in that widen() is only called if the object is not a char |
| stream (i.e., not basic_ostream<char>), so it's irrelevant what the |
| value of widen(c) is otherwise. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| I propose to strike the Footnote. |
| </p> |
| <hr> |
| <a name="475"></a><h3><a name="475">475. May the function object passed to for_each modify the elements of the iterated sequence?</a></h3><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#WP">WP</a> <b>Submitter:</b> Stephan T. Lavavej, Jaakko Jarvi <b>Date:</b> 9 Jul 2004</p> |
| <p> |
| It is not clear whether the function object passed to for_each is allowed to |
| modify the elements of the sequence being iterated over. |
| </p> |
| |
| <p> |
| for_each is classified without explanation in [lib.alg.nonmodifying], "25.1 |
| Non-modifying sequence operations". 'Non-modifying sequence operation' is |
| never defined. |
| </p> |
| |
| <p> |
| 25(5) says: "If an algorithm's Effects section says that a value pointed to |
| by any iterator passed as an argument is modified, then that algorithm has |
| an additional type requirement: The type of that argument shall satisfy the |
| requirements of a mutable iterator (24.1)." |
| </p> |
| |
| <p>for_each's Effects section does not mention whether arguments can be |
| modified:</p> |
| |
| <blockquote> |
| "Effects: Applies f to the result of dereferencing every iterator in the |
| range [first, last), starting from first and proceeding to last - 1." |
| </blockquote> |
| |
| <p> |
| Every other algorithm in [lib.alg.nonmodifying] is "really" non-modifying in |
| the sense that neither the algorithms themselves nor the function objects |
| passed to the algorithms may modify the sequences or elements in any way. |
| This DR affects only for_each. |
| </p> |
| |
| <p> |
| We suspect that for_each's classification in "non-modifying sequence |
| operations" means that the algorithm itself does not inherently modify the |
| sequence or the elements in the sequence, but that the function object |
| passed to it may modify the elements it operates on. |
| </p> |
| |
| <p> |
| The original STL document by Stepanov and Lee explicitly prohibited the |
| function object from modifying its argument. |
| The "obvious" implementation of for_each found in several standard library |
| implementations, however, does not impose this restriction. |
| As a result, we suspect that the use of for_each with function objects that modify |
| their arguments is wide-spread. |
| If the restriction was reinstated, all such code would become non-conforming. |
| Further, none of the other algorithms in the Standard |
| could serve the purpose of for_each (transform does not guarantee the order in |
| which its function object is called). |
| </p> |
| |
| <p> |
| We suggest that the standard be clarified to explicitly allow the function object |
| passed to for_each modify its argument.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a nonnormative note to the Effects in 25.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.foreach"> [lib.alg.foreach]</a>: If |
| the type of 'first' satisfies the requirements of a mutable iterator, |
| 'f' may apply nonconstant functions through the dereferenced iterators |
| passed to it. |
| </p> |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes that nothing in the standard prohibits function |
| objects that modify the sequence elements. The problem is that |
| for_each is in a secion entitled "nonmutating algorithms", and the |
| title may be confusing. A nonnormative note should clarify that.</p> |
| <hr> |
| <a name="478"><h3>478. Should forward iterator requirements table have a line for r->m?</h3></a><p><b>Section:</b> 24.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-iterators.html#lib.forward.iterators"> [lib.forward.iterators]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 11 Jul 2004</p> |
| <p> |
| The Forward Iterator requirements table contains the following: |
| </p> |
| <pre> expression return type operational precondition |
| semantics |
| ========== ================== =========== ========================== |
| a->m U& if X is mutable, (*a).m pre: (*a).m is well-defined. |
| otherwise const U& |
| |
| r->m U& (*r).m pre: (*r).m is well-defined. |
| </pre> |
| |
| <p>The second line may be unnecessary. Paragraph 11 of |
| [lib.iterator.requirements] says: |
| </p> |
| |
| <blockquote> |
| In the following sections, a and b denote values of type const X, n |
| denotes a value of the difference type Distance, u, tmp, and m |
| denote identifiers, r denotes a value of X&, t denotes a value of |
| value type T, o denotes a value of some type that is writable to |
| the output iterator. |
| </blockquote> |
| |
| <p> |
| Because operators can be overloaded on an iterator's const-ness, the |
| current requirements allow iterators to make many of the operations |
| specified using the identifiers a and b invalid for non-const |
| iterators.</p> |
| |
| <p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#477">477</a></p> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Remove the "r->m" line from the Forward Iterator requirements |
| table. Change</p> |
| <blockquote> |
| "const X" |
| </blockquote> |
| |
| <p> to </p> |
| |
| <blockquote> |
| "X or const X" |
| </blockquote> |
| |
| <p>in paragraph 11 of [lib.iterator.requirements].</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This is a defect because it constrains an lvalue to returning a modifiable lvalue. |
| </p> |
| <hr> |
| <a name="495"><h3>495. Clause 22 template parameter requirements</h3></a><p><b>Section:</b> 22 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-locales.html#lib.localization"> [lib.localization]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 10 Jan 2005</p> |
| <p>It appears that there are no requirements specified for many of the |
| template parameters in clause 22. It looks like this issue has never |
| come up, except perhaps for Facet.</p> |
| |
| <p>Clause 22 isn't even listed in 17.3.2.1 [lib.type.descriptions], |
| either, which is the wording that allows requirements on template |
| parameters to be identified by name.</p> |
| |
| <p>So one issue is that 17.3.2.1 [lib.type.descriptions] Should be |
| changed to cover clause 22. A better change, which will cover us in |
| the future, would be to say that it applies to all the library |
| clauses. Then if a template gets added to any library clause we are |
| covered.</p> |
| |
| <p>charT, InputIterator, and other names with requirements defined |
| elsewhere are fine, assuming the 17.3.2.1 [lib.type.descriptions] fix. |
| But there are a few template arguments names which I don't think have |
| requirements given elsewhere:</p> |
| |
| <ul> |
| <li>internT and externT. The fix is to add wording saying that internT |
| and externT must meet the same requirements as template arguments |
| named charT.</li> |
| |
| <li>stateT. I'm not sure about this one. There already is some wording, |
| but it seems a bit vague.</li> |
| |
| <li>Intl. [lib.locale.moneypunct.byname] The fix for this one is to |
| rename "Intl" to "International". The name is important because other |
| text identifies the requirements for the name International but not |
| for Intl.</li> |
| </ul> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 17.3.2.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-intro.html#lib.type.descriptions"> [lib.type.descriptions]</a>, paragraph 1, from:</p> |
| <blockquote> |
| The Requirements subclauses may describe names that are used to |
| specify constraints on template arguments.153) These names are used in |
| clauses 20, 23, 25, and 26 to describe the types that may be supplied |
| as arguments by a C++ program when instantiating template components |
| from the library. |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| The Requirements subclauses may describe names that are used to |
| specify constraints on template arguments.153) These names are used in |
| library clauses to describe the types that may be supplied as |
| arguments by a C++ program when instantiating template components from |
| the library. |
| </blockquote> |
| |
| <p>In the front matter of class 22, locales, add:</p> |
| <blockquote> |
| Template parameter types internT and externT shall meet the |
| requirements of charT (described in 21 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.strings"> [lib.strings]</a>). |
| </blockquote> |
| <p><b>Rationale:</b></p> |
| <p> |
| Again, a blanket clause isn't blanket enough. Also, we've got a |
| couple of names that we don't have blanket requirement statements |
| for. The only issue is what to do about stateT. This wording is |
| thin, but probably adequate.</p> |
| <hr> |
| <a name="496"><h3>496. Illegal use of "T" in vector<bool></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#WP">WP</a> <b>Submitter:</b> richard@ex-parrot.com <b>Date:</b> 10 Feb 2005</p> |
| <p> |
| In the synopsis of the std::vector<bool> specialisation in 23.2.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.vector"> [lib.vector]</a>, |
| the non-template assign() function has the signature</p> |
| |
| <pre> void assign( size_type n, const T& t ); |
| </pre> |
| |
| <p>The type, T, is not defined in this context.</p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace "T" with "value_type".</p> |
| <hr> |
| <a name="497"><h3>497. meaning of numeric_limits::traps for floating point types</h3></a><p><b>Section:</b> 18.2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-support.html#lib.numeric.limits.members"> [lib.numeric.limits.members]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 2 Mar 2005</p> |
| |
| <p>18.2.1.2, p59 says this much about the traps member of numeric_limits:</p> |
| |
| <blockquote> |
| <p>static const bool traps;<br> |
| -59- true if trapping is implemented for the type.204) |
| <br> |
| Footnote 204: Required by LIA-1. |
| </p> |
| </blockquote> |
| |
| <p>It's not clear what is meant by "is implemented" here.</p> |
| |
| <p> |
| In the context of floating point numbers it seems reasonable to expect |
| to be able to use traps to determine whether a program can "safely" use |
| infinity(), quiet_NaN(), etc., in arithmetic expressions, that is |
| without causing a trap (i.e., on UNIX without having to worry about |
| getting a signal). When traps is true, I would expect any of the |
| operations in section 7 of IEEE 754 to cause a trap (and my program |
| to get a SIGFPE). So, for example, on Alpha, I would expect traps |
| to be true by default (unless I compiled my program with the -ieee |
| option), false by default on most other popular architectures, |
| including IA64, MIPS, PA-RISC, PPC, SPARC, and x86 which require |
| traps to be explicitly enabled by the program. |
| </p> |
| |
| <p> |
| Another possible interpretation of p59 is that traps should be true |
| on any implementation that supports traps regardless of whether they |
| are enabled by default or not. I don't think such an interpretation |
| makes the traps member very useful, even though that is how traps is |
| implemented on several platforms. It is also the only way to implement |
| traps on platforms that allow programs to enable and disable trapping |
| at runtime. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Change p59 to read:</p> |
| <blockquote>True if, at program startup, there exists a value of the type that |
| would cause an arithmetic operation using that value to trap.</blockquote> |
| <p><b>Rationale:</b></p> |
| <p> |
| Real issue, since trapping can be turned on and off. Unclear what a |
| static query can say about a dynamic issue. The real advice we should |
| give users is to use cfenv for these sorts of queries. But this new |
| proposed resolution is at least consistent and slightly better than |
| nothing.</p> |
| <hr> |
| <a name="505"><h3>505. Result_type in random distribution requirements</h3></a><p><b>Section:</b> TR1 5.1.1 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.req"> [tr.rand.req]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| Table 17: Random distribution requirements |
| </p> |
| <p> |
| Row 1 requires that each random distribution provide a nested type "input_type"; |
| this type denotes the type of the values that the distribution consumes. |
| </p> |
| <p> |
| Inspection of all distributions in [tr.rand.dist] reveals that each distribution |
| provides a second typedef ("result_type") that denotes the type of the values the |
| distribution produces when called. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| It seems to me that this is also a requirement |
| for all distributions and should therefore be indicated as such via a new second |
| row to this table 17: |
| </p> |
| <table border="1" cellpadding="5"> |
| <tbody><tr> |
| <td>X::result_type</td> |
| <td>T</td> |
| <td>---</td> |
| <td>compile-time</td> |
| </tr> |
| </tbody></table> |
| |
| <p><i>[ |
| Berlin: Voted to WP. N1932 adopts the proposed resolution: see Table 5 row 1. |
| ]</i></p> |
| |
| <hr> |
| <a name="507"><h3>507. Missing requirement for variate_generator::operator()</h3></a><p><b>Section:</b> TR1 5.1.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.var"> [tr.rand.var]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| Paragraph 11 of [tr.rand.var] equires that the member template |
| </p> |
| <blockquote><pre>template<class T> result_type operator() (T value); |
| </pre></blockquote> |
| <p> |
| return |
| </p> |
| <blockquote><pre>distribution()(e, value) |
| </pre></blockquote> |
| <p> |
| However, not all distributions have an operator() with a corresponding signature. |
| </p> |
| |
| <p><i>[ |
| Berlin: As a working group we voted in favor of N1932 which makes this moot: |
| variate_generator has been eliminated. Then in full committee we voted to give |
| this issue WP status (mistakenly). |
| ]</i></p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| We therefore recommend that we insert the following precondition before paragraph 11: |
| </p> |
| <blockquote> |
| Precondition: <tt>distribution().operator()(e,value)</tt> is well-formed. |
| </blockquote> |
| <hr> |
| <a name="508"><h3>508. Bad parameters for ranlux64_base_01</h3></a><p><b>Section:</b> TR1 5.1.5 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.rand.predef"> [tr.rand.predef]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| The fifth of these engines with predefined parameters, ranlux64_base_01, |
| appears to have an unintentional error for which there is a simple correction. |
| The two pre-defined subtract_with_carry_01 engines are given as: |
| </p> |
| <blockquote><pre>typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01; |
| typedef subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01; |
| </pre></blockquote> |
| <p> |
| We demonstrate below that ranlux64_base_01 fails to meet the intent of the |
| random number generation proposal, but that the simple correction to |
| </p> |
| <blockquote><pre>typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01; |
| </pre></blockquote> |
| <p> |
| does meet the intent of defining well-known good parameterizations. |
| </p> |
| <p> |
| The ranlux64_base_01 engine as presented fails to meet the intent for |
| predefined engines, stated in proposal N1398 (section E): |
| </p> |
| <blockquote><p> |
| In order to make good random numbers available to a large number of library |
| users, this proposal not only defines generic random-number engines, but also |
| provides a number of predefined well-known good parameterizations for those. |
| </p></blockquote> |
| <p> |
| The predefined ranlux_base_01 engine has been proven [1,2,3] to have a very |
| long period and so meets this criterion. This property makes it suitable for |
| use in the excellent discard_block engines defined subsequently. The proof |
| of long period relies on the fact (proven in [1]) that 2**(w*r) - 2**(w*s) |
| + 1 is prime (w, r, and s are template parameters to subtract_with_carry_01, |
| as defined in [tr.rand.eng.sub1]). |
| </p> |
| <p> |
| The ranlux64_base_01 engine as presented in [tr.rand.predef] uses w=48, r=24, s=10. |
| For these numbers, the combination 2**(w*r)-2**(w*s)+1 is non-prime (though |
| explicit factorization would be a challenge). In consequence, while it is |
| certainly possible for some seeding states that this engine would have a very |
| long period, it is not at all Òwell-knownÓ that this is the case. The intent |
| in the N1398 proposal involved the base of the ranlux64 engine, which finds heavy |
| use in the physics community. This is isomorphic to the predefined ranlux_base_01, |
| but exploits the ability of double variables to hold (at least) 48 bits of mantissa, |
| to deliver 48 random bits at a time rather than 24. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| To achieve this intended behavior, the correct template parameteriztion would be: |
| </p> |
| <blockquote><pre>typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01; |
| </pre></blockquote> |
| <p> |
| The sequence of mantissa bits delivered by this is isomorphic (treating each |
| double as having the bits of two floats) to that delivered by ranlux_base_01. |
| </p> |
| <p> |
| <b>References:</b> |
| </p> |
| <ol> |
| <li>F. James, Comput. Phys. Commun. 60(1990) 329</li> |
| <li>G. Marsaglia and A. Zaman, Ann. Appl. Prob 1(1991) 462</li> |
| <li>M. Luscher, Comput. Phys. Commun. 79(1994) 100-110</li> |
| </ol> |
| |
| <p><i>[ |
| Berlin: Voted to WP. N1932 adopts the proposed resolution in 26.3.5, |
| just above paragraph 5. |
| ]</i></p> |
| |
| <hr> |
| <a name="519"><h3>519. Data() undocumented</h3></a><p><b>Section:</b> TR1 6.2.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.array.array"> [tr.array.array]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| <tt>array<>::data()</tt> is present in the class synopsis, but not documented. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a new section, after 6.2.2.3: |
| </p> |
| <blockquote><pre>T* data() |
| const T* data() const; |
| </pre></blockquote> |
| <p> |
| <b>Returns:</b> <tt>elems</tt>. |
| </p> |
| <p> |
| Change 6.2.2.4/2 to: |
| </p> |
| <blockquote> |
| In the case where <tt>N == 0</tt>, <tt>begin() == end()</tt>. The return value |
| of <tt>data()</tt> is unspecified. |
| </blockquote> |
| <hr> |
| <a name="520"><h3>520. Result_of and pointers to data members</h3></a><p><b>Section:</b> TR1 3.6 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.func.bind"> [tr.func.bind]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| In the original proposal for binders, the return type of bind() when |
| called with a pointer to member data as it's callable object was |
| defined to be mem_fn(ptr); when Peter Dimov and I unified the |
| descriptions of the TR1 function objects we hoisted the descriptions |
| of return types into the INVOKE pseudo-function and into result_of. |
| Unfortunately, we left pointer to member data out of result_of, so |
| bind doesn't have any specified behavior when called with a pointer |
| to member data. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[ |
| Pete and Peter will provide wording. |
| ]</i></p> |
| |
| <p> |
| In 20.5.4 [lib.func.ret] ([tr.func.ret]) p3 add the following bullet after bullet 2: |
| </p> |
| <ol start="3"> |
| <li>If <tt>F</tt> is a member data pointer type <tt>R T::*</tt>, <tt>type</tt> |
| shall be <tt><i>cv</i> R&</tt> when <tt>T1</tt> is <tt><i>cv</i> U1&</tt>, |
| <tt>R</tt> otherwise.</li> |
| </ol> |
| |
| <p><i>[ |
| Peter provided wording. |
| ]</i></p> |
| <hr> |
| <a name="521"><h3>521. Garbled requirements for argument_type in reference_wrapper</h3></a><p><b>Section:</b> TR1 2.1.2 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.util.refwrp.refwrp"> [tr.util.refwrp.refwrp]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Pete Becker <b>Date:</b> 3 Jul 2005</p> |
| <p> |
| 2.1.2/3, second bullet item currently says that reference_wrapper<T> is |
| derived from unary_function<T, R> if T is: |
| </p> |
| <blockquote> |
| a pointer to member function type with cv-qualifier cv and no arguments; |
| the type T1 is cv T* and R is the return type of the pointer to member function; |
| </blockquote> |
| <p> |
| The type of T1 can't be cv T*, 'cause that's a pointer to a pointer to member |
| function. It should be a pointer to the class that T is a pointer to member of. |
| Like this: |
| </p> |
| <blockquote> |
| a pointer to a member function R T0::f() cv (where cv represents the member |
| function's cv-qualifiers); the type T1 is cv T0* |
| </blockquote> |
| <p> |
| Similarly, bullet item 2 in 2.1.2/4 should be: |
| </p> |
| <blockquote> |
| a pointer to a member function R T0::f(T2) cv (where cv represents the member |
| function's cv-qualifiers); the type T1 is cv T0* |
| </blockquote> |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change bullet item 2 in 2.1.2/3: |
| </p> |
| |
| <blockquote> |
| <ul> |
| <li> |
| a pointer to member function <del>type with cv-qualifier <tt><i>cv</i></tt> and no arguments; |
| the type <tt>T1</tt> is <tt><i>cv</i> T*</tt> and <tt>R</tt> is the return |
| type of the pointer to member function</del> <ins><tt>R T0::f() <i>cv</i></tt> |
| (where <tt><i>cv</i></tt> represents the member function's cv-qualifiers); |
| the type <tt>T1</tt> is <tt><i>cv</i> T0*</tt></ins> |
| </li> |
| </ul> |
| </blockquote> |
| |
| <p> |
| Change bullet item 2 in 2.1.2/4: |
| </p> |
| |
| <blockquote> |
| <ul> |
| <li> |
| a pointer to member function <del>with cv-qualifier <tt><i>cv</i></tt> and taking one argument |
| of type <tt>T2</tt>; the type <tt>T1</tt> is <tt><i>cv</i> T*</tt> and |
| <tt>R</tt> is the return type of the pointer to member function</del> |
| <ins><tt>R T0::f(T2) <i>cv</i></tt> (where <tt><i>cv</i></tt> represents the member |
| function's cv-qualifiers); the type <tt>T1</tt> is <tt><i>cv</i> T0*</tt></ins> |
| </li> |
| </ul> |
| </blockquote> |
| |
| <hr> |
| <a name="530"><h3>530. Must elements of a string be contiguous?</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#WP">WP</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 15 Nov 2005</p> |
| <p>Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#69">69</a>, which was incorporated into C++03, mandated |
| that the elements of a vector must be stored in contiguous memory. |
| Should the same also apply to <tt>basic_string</tt>?</p> |
| |
| <p>We almost require contiguity already. Clause 23.3.4 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-containers.html#lib.multiset"> [lib.multiset]</a> |
| defines <tt>operator[]</tt> as <tt>data()[pos]</tt>. What's missing |
| is a similar guarantee if we access the string's elements via the |
| iterator interface.</p> |
| |
| <p>Given the existence of <tt>data()</tt>, and the definition of |
| <tt>operator[]</tt> and <tt>at</tt> in terms of <tt>data</tt>, |
| I don't believe it's possible to write a useful and standard- |
| conforming <tt>basic_string</tt> that isn't contiguous. I'm not |
| aware of any non-contiguous implementation. We should just require |
| it. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text to the end of 21.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.basic.string"> [lib.basic.string]</a>, |
| paragraph 2. </p> |
| |
| <blockquote> |
| <p>The characters in a string are stored contiguously, meaning that if |
| <tt>s</tt> is a <tt>basic_string<charT, Allocator></tt>, then |
| it obeys the identity |
| <tt>&*(s.begin() + n) == &*s.begin() + n</tt> |
| for all <tt>0 <= n < s.size()</tt>. |
| </p> |
| </blockquote> |
| <hr> |
| <a name="533"><h3>533. typo in 2.2.3.10/1</h3></a><p><b>Section:</b> TR1 2.2.3.10 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.util.smartptr.getdeleter"> [tr.util.smartptr.getdeleter]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> <b>Submitter:</b> Paolo Carlini <b>Date:</b> 9 Nov 2005</p> |
| <p> |
| I'm seeing something that looks like a typo. The Return of <tt>get_deleter</tt> |
| says: |
| </p> |
| <blockquote> |
| If <tt>*this</tt> <i>owns</i> a deleter <tt>d</tt>... |
| </blockquote> |
| <p> |
| but <tt>get_deleter</tt> is a free function! |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Therefore, I think should be: |
| </p> |
| <blockquote> |
| If <tt><del>*this</del> <ins>p</ins></tt> <i>owns</i> a deleter <tt>d</tt>... |
| </blockquote> |
| <hr> |
| <a name="535"><h3>535. std::string::swap specification poorly worded</h3></a><p><b>Section:</b> 21.3.5.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-strings.html#lib.string::swap"> [lib.string::swap]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Beman Dawes <b>Date:</b> 14 Dec 2005</p> |
| <p> |
| std::string::swap currently says for effects and postcondition: |
| </p> |
| |
| <blockquote> |
| <p> |
| <i>Effects:</i> Swaps the contents of the two strings. |
| </p> |
| |
| <p> |
| <i>Postcondition:</i> <tt>*this</tt> contains the characters that were in <tt><i>s</i></tt>, |
| <tt><i>s</i></tt> contains the characters that were in <tt>*this</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| Specifying both Effects and Postcondition seems redundant, and the postcondition |
| needs to be made stronger. Users would be unhappy if the characters were not in |
| the same order after the swap. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <blockquote> |
| <p> |
| <del><i>Effects:</i> Swaps the contents of the two strings.</del> |
| </p> |
| |
| <p> |
| <i>Postcondition:</i> <tt>*this</tt> contains the <ins>same sequence of</ins> |
| characters that <del>were</del> <ins>was</ins> in <tt><i>s</i></tt>, |
| <tt><i>s</i></tt> contains the <ins>same sequence of</ins> characters that |
| <del>were</del> <ins>was</ins> in <tt>*this</tt>. |
| </p> |
| </blockquote> |
| <hr> |
| <a name="537"><h3>537. Typos in the signatures in 27.6.1.3/42-43 and 27.6.2.4</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#WP">WP</a> <b>Submitter:</b> Paolo Carlini <b>Date:</b> 12 Feb 2006</p> |
| <p> |
| In the most recent working draft, I'm still seeing: |
| </p> |
| |
| <blockquote><pre>seekg(off_type& off, ios_base::seekdir dir) |
| </pre></blockquote> |
| |
| <p> |
| and |
| </p> |
| |
| <blockquote><pre>seekp(pos_type& pos) |
| |
| seekp(off_type& off, ios_base::seekdir dir) |
| </pre></blockquote> |
| |
| <p> |
| that is, by reference off and pos arguments. |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| After 27.6.1.3p42 change: |
| </p> |
| |
| <blockquote><pre>basic_istream<charT,traits>& seekg(off_type<del>&</del> <i>off</i>, ios_base::seekdir <i>dir</i>); |
| </pre></blockquote> |
| |
| <p> |
| After 27.6.2.4p1 change: |
| </p> |
| |
| <blockquote><pre>basic_ostream<charT,traits>& seekp(pos_type<del>&</del> <i>pos</i>); |
| </pre></blockquote> |
| |
| <p> |
| After 27.6.2.4p3 change: |
| </p> |
| |
| <blockquote><pre>basic_ostream<charT,traits>& seekp(off_type<del>&</del> <i>off</i>, ios_base::seekdir <i>dir</i>); |
| </pre></blockquote> |
| <hr> |
| <a name="538"></a><h3><a name="538">538. 241 again: Does unique_copy() require CopyConstructible and Assignable?</a></h3><p><b>Section:</b> 25.2.8 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 9 Feb 2006</p> |
| <p> |
| I believe I botched the resolution of |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241"> |
| 241 "Does unique_copy() require CopyConstructible and Assignable?"</a> which now |
| has WP status. |
| </p> |
| |
| <p> |
| This talks about <tt>unique_copy</tt> requirements and currently reads: |
| </p> |
| |
| <blockquote> |
| -5- <i>Requires:</i> The ranges <tt>[<i>first</i>, <i>last</i>)</tt> and |
| <tt>[<i>result</i>, <i>result</i>+(<i>last</i>-<i>first</i>))</tt> |
| shall not overlap. The expression <tt>*<i>result</i> = *<i>first</i></tt> shall |
| be valid. If neither <tt>InputIterator</tt> nor <tt>OutputIterator</tt> meets the |
| requirements of forward iterator then the value type of <tt>InputIterator</tt> |
| must be CopyConstructible (20.1.3). Otherwise CopyConstructible is not required. |
| </blockquote> |
| |
| <p> |
| The problem (which Paolo discovered) is that when the iterators are at their |
| most restrictive (<tt>InputIterator</tt>, <tt>OutputIterator</tt>), then we want |
| <tt>InputIterator::value_type</tt> to be both <tt>CopyConstructible</tt> and |
| <tt>CopyAssignable</tt> (for the most efficient implementation). However this |
| proposed resolution only makes it clear that it is <tt>CopyConstructible</tt>, |
| and that one can assign from <tt>*<i>first</i></tt> to <tt>*<i>result</i></tt>. |
| This latter requirement does not necessarily imply that you can: |
| </p> |
| |
| <blockquote><pre>*<i>first</i> = *<i>first</i>; |
| </pre></blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <blockquote> |
| -5- <i>Requires:</i> The ranges <tt>[<i>first</i>, <i>last</i>)</tt> and |
| <tt>[<i>result</i>, <i>result</i>+(<i>last</i>-<i>first</i>))</tt> |
| shall not overlap. The expression <tt>*<i>result</i> = *<i>first</i></tt> |
| shall |
| be valid. If neither <tt>InputIterator</tt> nor <tt>OutputIterator</tt> meets the |
| requirements of forward iterator then the <del>value type</del> |
| <ins><tt>value_type</tt></ins> of <tt>InputIterator</tt> |
| must be CopyConstructible (20.1.3) <ins>and Assignable</ins>. |
| Otherwise CopyConstructible is not required. |
| </blockquote> |
| <hr> |
| <a name="540"><h3>540. shared_ptr<void>::operator*()</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#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 15 Oct 2005</p> |
| <p> |
| I'm trying to reconcile the note in tr.util.smartptr.shared.obs, p6 |
| that talks about the operator*() member function of shared_ptr: |
| </p> |
| |
| <blockquote> |
| Notes: When T is void, attempting to instantiate this member function |
| renders the program ill-formed. [Note: Instantiating shared_ptr<void> |
| does not necessarily result in instantiating this member function. |
| --end note] |
| </blockquote> |
| |
| <p> |
| with the requirement in temp.inst, p1: |
| </p> |
| |
| <blockquote> |
| The implicit instantiation of a class template specialization causes |
| the implicit instantiation of the declarations, but not of the |
| definitions... |
| </blockquote> |
| |
| <p> |
| I assume that what the note is really trying to say is that |
| "instantiating shared_ptr<void> *must not* result in instantiating |
| this member function." That is, that this function must not be |
| declared a member of shared_ptr<void>. Is my interpretation |
| correct? |
| </p> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 2.2.3.5p6 |
| </p> |
| |
| <blockquote> |
| -6- <del><i>Notes:</i></del> When <tt>T</tt> is <tt>void</tt>, <del>attempting to instantiate |
| this member function renders the program ill-formed. [<i>Note:</i> |
| Instantiating <tt>shared_ptr<void></tt> does not necessarily result in |
| instantiating this member function. <i>--end note</i>]</del> <ins>it is |
| unspecified whether this member function is declared or not, and if so, what its |
| return type is, except that the declaration (although not necessarily the |
| definition) of the function shall be well-formed.</ins> |
| </blockquote> |
| |
| <hr> |
| <a name="541"><h3>541. shared_ptr template assignment and void</h3></a><p><b>Section:</b> TR1 2.2.3 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/tr1.html#tr.util.smartptr.shared"> [tr.util.smartptr.shared]</a> <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 16 Oct 2005</p> |
| <p> |
| Is the void specialization of the template assignment operator taking |
| a shared_ptr<void> as an argument supposed be well-formed? |
| </p> |
| <p> |
| I.e., is this snippet well-formed: |
| </p> |
| <blockquote><pre>shared_ptr<void> p; |
| p.operator=<void>(p); |
| </pre></blockquote> |
| |
| <p> |
| Gcc complains about auto_ptr<void>::operator*() returning a reference |
| to void. I suspect it's because shared_ptr has two template assignment |
| operators, one of which takes auto_ptr, and the auto_ptr template gets |
| implicitly instantiated in the process of overload resolution. |
| </p> |
| |
| <p> |
| The only way I see around it is to do the same trick with auto_ptr<void> |
| operator*() as with the same operator in shared_ptr<void>. |
| </p> |
| |
| <p> |
| PS Strangely enough, the EDG front end doesn't mind the code, even |
| though in a small test case (below) I can reproduce the error with |
| it as well. |
| </p> |
| |
| <blockquote><pre>template <class T> |
| struct A { T& operator*() { return *(T*)0; } }; |
| |
| template <class T> |
| struct B { |
| void operator= (const B&) { } |
| template <class U> |
| void operator= (const B<U>&) { } |
| template <class U> |
| void operator= (const A<U>&) { } |
| }; |
| |
| int main () |
| { |
| B<void> b; |
| b.operator=<void>(b); |
| } |
| </pre></blockquote> |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In [lib.memory] change: |
| </p> |
| <blockquote><pre>template<class X> class auto_ptr; |
| <ins>template<> class auto_ptr<void>;</ins> |
| </pre></blockquote> |
| |
| <p> |
| In [lib.auto.ptr]/2 add the following before the last closing brace: |
| </p> |
| |
| <blockquote><pre>template<> class auto_ptr<void> |
| { |
| public: |
| typedef void element_type; |
| }; |
| </pre></blockquote> |
| |
| <p>----- End of document -----</p> |
| </body></html> |