Подробности
[В начало]
Проблема в реализации № S0738
Краткое описание
Неверная интерпретация CHAR_MAX в строке группировки в monetary и numeric facet'ах
Подробное описание
Описание функции numpunct<>::do_grouping() (22.2.3.1.2, p3):
Returns: A basic_string<char> vec used as a vector of integer values, in which each element vec[i] represents the number of digits in the group at position i, starting with position 0 as the rightmost group. If vec.size() <= i, the number is the same as group (i-1); if (i<0 || vec[i]<=0 || vec[i]==CHAR_MAX), the size of the digit group is unlimited.
Однако реализации num_put и num_get не воспринимают условие (vec[i]==CHAR_MAX) как условие неограниченного размера группы - число CHAR_MAX воспринимается как обычный размер группы.
Описание функции moneypunct<charT, Intl>::do_grouping() ссылается на numpunct<>::do_grouping() (22.2.6.3.2, p3):
Однако у реализаций money_put и money_get те же проблемы, что и у num_put и num_get.
Приведенные ниже примеры демонстрируют эти проблемы на строке группировки, состоящей из одного символа CHAR_MAX. Согласно приведенному выше описанию, это должно расцениватся как отсутствие группировки вообще. Но реализация ведет себя иначе.
Раздел стандарта
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.3.1.2
Пример
//*********Example 1************ #include <locale> #include <sstream> #include <iostream> using namespace std; class my_numpunct : public numpunct<char> { protected: string do_grouping()const{return string(1, CHAR_MAX);} }; int main() { locale loc(locale(), new my_numpunct()); istringstream ss("123,456"); ss.imbue(loc); long double l = -1; ios_base::iostate err; use_facet<num_get<char> >(loc).get(ss, 0, ss, err, l); cout << l << endl; //123456 will be output, but should be 123, // because ',' shouldn't be read when no grouping return 0; } //*********Example 2************ #include <locale> #include <sstream> #include <iostream> using namespace std; class my_moneypunct : public moneypunct<char> { protected: string do_grouping()const{return string(1, CHAR_MAX);} }; int main() { locale loc(locale(), new my_moneypunct()); ostringstream ss(""); ss.imbue(loc); long double l = 1.e300L; use_facet<money_put<char> >(loc).put(ss, false, ss, ' ', l); cout << ss.str().size() << endl; /* * Will be output 303, * which means that beside of 301 - number of digits in 1.e300 - * two ',' exist in number representation. * But grouping string means no grouping. */ return 0; }
Компонент
libstdc++
Окружение
Архитектуры
x86, x86-64, IA64
Принято
GCC Bugzilla 39168
Статус
Иcправлено в gcc-4.4.0
[В начало]