Подробности
[В начало]
Проблема в реализации № S0711
Краткое описание
num_put<>::do_put(bool) неверно выполняет 'internal' padding для случая boolalpha==true
Подробное описание
Из описания функции num_put<>::do_put(bool) (раздел 22.2.2.2.2):
iter_type put(iter_type out, ios_base& str, char_type fill, bool val) const;Effects: If (str.flags()&ios_base::boolalpha)==0 then do
out = do_put(out, str, fill, (int)val)
Otherwise do
const numpunct
string_type s = val ? np.truename() : np.falsename();
and then insert the characters of s into out.
Примечание. "put" вместо "do_put" в сигнатуре функции - это опечатка, подробнее см. здесь
Не уточняется, как именно выполняется вставка символов строки s в итератор out. Судя по всему, заполнение строки (padding) до необходимой длины выполняется так же, как и для остальных функций семейства num_put<>::do_put() (22.2.2.2.2 p19 Table 61):
- adjustfield == iosbase::left - pad after
- adjustfield == iosbase::right - pad before
- adjustfield == internal and a sign occurs in the representation - pad after the sign
- adjustfield == internal and representation after stage 1 began with 0x or 0X - pad after x or X
- otherwise pad before
Однако, num_put<>::do_put(bool) должен вывести строку, которая, в общем случае, не является строковым представлением числа. В таких строках выделение знака или сочетаний "0x" и "0X" лишено смысла. То есть в данном случае флаг 'internal' должен быть эквивалентен 'right' - "pad before".
Именно так реализован оператор вывода последовательности символов в поток (operator<< для const charT*). Хотя описание заполнения (padding) этой последовательности (27.6.2.5.4, p2) ссылается на num_put<>::do_put, на практике флаг 'internal' ведет себя также, как и 'right' в данном случае, что логично.
Однако реализация num_put<>::do_put(bool) при выполнении internal padding ведет себя так же, как и остальные функции семейства num_put<>::do_put - отделяет знак и сочетание "0x"/"0X" от остального содержимого строки.
В приведённом ниже примере выводится "- no-", хотя должно быть выведено " -no-".
Раздел стандарта
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.2.2
Пример
#include <iostream> #include <locale> using namespace std; class my_numpunct : public numpunct<char> { protected: string do_falsename() const {return "-no-";} }; int main() { locale my_loc = locale(locale::classic(), new my_numpunct()); cout.imbue(my_loc); cout.width(6); bool b = false; cout << internal << boolalpha << b << endl; // "- no-" is output instead of " -no-" return 0; }
Компонент
libstdc++
Принято
GCC Bugzilla 38196
Статус
Исправлено в gcc-4.4.0
[В начало]