Details
[Home]
Issue of the Implementation # S0736
Brief
Wrong behaviour of num_get<>::do_get(bool) in the case when one target sequence is a prefix of the other one
Detailed Description
The description of the function
iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, bool& val) const
states the following for the case when (str.flags() & ios_base::boolalpha) != 0 (22.2.2.1.2, p15):
It follows from this description that if a target sequence (returned by truename() or falsename()) is a prefix of the other one, the function should continue reading from the stream after it has read the shorter target sequence. The function should do so to find if there is a unique match with the other target sequence. Only if the next character in the stream does not match the corresponding character in the longer target sequence (or if there are no more characters in the stream, in == end) should the function stop reading. The example given in the standard right after the description of do_get() demonstrates this case:
For targets true: "a" and false: "abb", the input sequence "a" yields val == true and err == str.eofbit.If, however, the next character in the stream matches the corresponding character in the longer target sequence, the function should continue reading to determine if the input matches the longer target sequence. The fact that a part of the input coincides with the shorter target sequence should be ignored in this case. The next example from the standard demonstrates this, the target sequences for true and false being the same as above):
the input sequence "abc" yields err = str.failbit, with in ending at the 'c'.However, the actual implementation of do_get() function sets err == str.goodbit (no error detected) and sets val to true. The remaining character sequence in the input stream is 'bc' after calling this function rather than 'c' as it should be according to the example from the standard. The sample program below demonstrates the problem.
Problem location(s) in the standard
Linux Standard Base C++ Specification 3.2, Chapter 9. Libraries, 9.1. Interfaces for libstdcxx that refers ISO/IEC 14882: 2003 Programming languages --C++, section 22.2.2.1.2
Example
#include <iostream> #include <sstream> #include <algorithm> using namespace std; class numpunct_my : public numpunct<char> { public: numpunct_my(size_t refs = 0) : numpunct<char>(refs) {} protected: ~numpunct_my(){}; string do_truename() const{return "a";} string do_falsename() const{return "abb";} }; int main() { istringstream is("abс"); is.imbue(locale(locale(), new numpunct_my())); bool result = false; is >> boolalpha >> result; if(is.rdstate() & ios_base::failbit) cout << "failbit was set." << endl; else cout << "failbit wasn't set, and result is " << boolalpha << result << endl; string rest_of_stream; copy((istreambuf_iterator<char>)is, istreambuf_iterator<char>(), back_insert_iterator<string>(rest_of_stream)); cout << "The rest of the stream is '" << rest_of_stream << "'." << endl; return 0; }
Component
libstdc++
Accepted
GCC Bugzilla 37957
Status
Fixed in gcc-4.4.0
[Home]