The C++ Standard, in section 22.2.6.1.1, says that if money_get::do_get
recognizes a valid sequence then it does not modify the ios_base::iostate
variable passed to it.  That variable should be set to eofbit only if do_get
has not recognized a valid sequence and no more characters are available.  This
was reported within IBM.

The testcase below gives the following output with GCC 3.3:

Contents of digits = "11"
Contents of retval = " 22"
mystate is goodbit as expected

and the following with later versions, including current mainline:

Contents of digits = "11"
Contents of retval = " 22"
mystate is eofbit, should not have changed

The testcase:

----------------------------------------------------------
#include <locale>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdlib>

// Declare our own version of money_get to get access to do_get.
struct MyMoneyGet : public std::money_get<char, char *>
{
  char *
  my_do_get (char *pa, char *pz, bool intl,
             std::ios_base &myios, std::ios_base::iostate &mystate,
             std::string &digits)
  {
    return do_get (pa, pz, intl, myios, mystate, digits);
  }
};

int
main ()
{
  std::string digits;
  MyMoneyGet mg;
  std::ios_base::iostate mystate;
  std::stringstream myios;
  std::locale mylocale (std::locale::classic (), new std::moneypunct<char>);

  myios.imbue (mylocale);
  char s1[] = "11 22";
  char s2[] = "11";             // use this to get the length we want
  char *retval;
  size_t len2 = strlen (s2);

  // Parse the string "11" from the larger string "11 12"; we do that
  // to be able to look at the return value in retval.
  mystate = std::ios_base::goodbit;
  retval = mg.my_do_get (s1, s1 + len2, false, myios, mystate, digits);
  printf ("Contents of digits = \"%s\"\n", digits.c_str ());
  printf ("Contents of retval = \"%s\"\n", retval);
  if (mystate == std::ios_base::goodbit)
    printf ("mystate is goodbit as expected\n");
  else
    {
      if (mystate == std::ios_base::eofbit)
        printf ("mystate is eofbit, should not have changed\n");
      else
        printf ("mystate is %d, should not have changed\n", mystate);
      abort ();
    }
}
-------------------------------------------------------------------

The behavior changed with:

    http://gcc.gnu.org/viewcvs?view=rev&rev=73011

    r73011 | paolo | 2003-10-28 17:09:03 +0000 (Tue, 28 Oct 2003)


-- 
           Summary: money_get:do_get incorrectly sets eofbit for valid input
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: janis at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34031

Reply via email to