Подробности
[В начало]
Проблема в реализации № S0735
Краткое описание
num_get<>::do_get(bool) неверно выставляет флаг eofbit в случае boolalpha == true
Подробное описание
Из описания функции
iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, bool& val) const
для случая, когда
(str.flags() & ios_base::boolalpha) != 0 (22.2.2.1.2):
Отсюда следует, что сравнение итераторов in и end будет происходить только тогда, когда последовательность, полученная из предыдущих вызовов (*in++), не совпадает ни с одной целевой последовательностью (truename() и falsename()), но может совпасть в будущем.
В частности, если truename = "true" и falsename = "false", то как только из потока были считаны символы 't', 'r', 'u', 'e', дальнейшего сравнения in и end не будет, хотя на этот момент возможно, что in == end.
Отсюда следует, что флаг eofbit выставляется только тогда, когда при чтении последовательности из потока обнаружилось, что in == end.
Это не эквивалентно тому, что после чтения последовательности in == end.
Однако реализация ведет себя так, что флаг eofbit выставляется тогда, когда на момент выхода из функции in == end (т.е эта проверка выполняется уже после того, как последовательность прочитана и выставлен/не выставлен результат).
Из-за этого, в частности, неверно выставляется значение err в следующих примерах, приведенных в стандарте после описания этой функции (22.2.2.1.2 p16):
For targets true: "1" and false: "0", the input sequence "1" yields val == true and err == str.goodbit. For empty targets (""), any input sequence yields err == str.failbit.В первом примере реализация выдает err = str.eofbit, а во втором случае при пустом потоке (in == end изначально) - err = str.failbit | str.eofbit.
В приведенном ниже примере показывается поведение функции в случае, когда
true соответствует строка "true", а false - "false" (значения целевых последовательностей в "C" локали, используемой по умолчанию), а входная последовательность - "true".
Согласно стандарту, флаг eofbit быть выставлен не должен, однако реализация его выставляет.
Раздел стандарта
Linux Standard Base C++ Specification 3.2, Chapter 9. Libraries, 9.1. Interfaces for libstdcxx, который ссылается на ISO/IEC 14882: 2003 Programming languages --C++, section 22.2.2.1.2
Пример
#include <iostream> #include <sstream> using namespace std; int main() { istringstream is("true"); bool result; is >> boolalpha >> result; if(is.rdstate() & ios_base::eofbit) cout << "eofbit was set." << endl; else cout << "eofbit wasn't set." << endl; return 0; }
Компонент
libstdc++
Принято
GCC Bugzilla 37958
Статус
Исправлено в gcc-4.4.0
[В начало]