2041. Stage 2 accumulate incompatibilty

Section: 28.3.4.3.2.3 [facet.num.get.virtuals] Status: C++11 Submitter: Howard Hinnant Opened: 2011-03-09 Last modified: 2016-01-28

Priority: Not Prioritized

View other active issues in [facet.num.get.virtuals].

View all other issues in [facet.num.get.virtuals].

View all issues with C++11 status.

Discussion:

num_get Stage 2 accumulation changed between C++03 and the current C++0x working draft. The sentences:

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.

have been dropped from 28.3.4.3.2.3 [facet.num.get.virtuals], Stage 2, paragraph 3 that begins:

If discard is true, […]

Consider this code:

#include <sstream>
#include <iostream>

int main(void)
{
   std::istringstream s("8cz");
   long i = 0;
   char c;
   s >> i;
   if (!s.fail())
       std::cout << "i = " << i << '\n';
   else
   {
       std::cout << "s >> i failed\n";
       s.clear();
   }
   s >> c;
   if (!s.fail())
       std::cout << "c = " << c << '\n';
   else
       std::cout << "s >> c failed\n";
}

C++0x currently prints out:

s >> i failed
c = z

However C++03 conforming implementations will output:

i = 8
c = c

I believe we need to restore C++03 compatibility.

Proposed resolution:

Add to 28.3.4.3.2.3 [facet.num.get.virtuals], Stage 2:

If discard is true, then if '.' has not yet been accumulated, then the position of the character is remembered, but the character is otherwise ignored. Otherwise, if '.' has already been accumulated, the character is discarded and Stage 2 terminates. 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.

If the character is either discarded or accumulated then in is advanced by ++in and processing returns to the beginning of stage 2.