Подробности

[В начало]

Проблема в реализации № 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):

Returns: A pattern defined identically as the result of numpunct<charT>::do_grouping()


Однако у реализаций 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

[В начало]