Details

[Home]

Issue of the Implementation # S0738

Brief

Incorrect interpritation of value CHAR_MAX inside grouping string in monetary and numeric facets

Detailed Description

Description of 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.


But num_put and num_get implementations don't interpret condition (vec[i]==CHAR_MAX) as condition of group with unlimited size, but interpret value CHAR_MAX as regular size of digits group.


Description of moneypunct<charT, Intl>::do_grouping() refers on numpunct<>::do_grouping() (22.2.6.3.2, p3):

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


But money_put и money_get have same problems, as num_put and num_get.


Examples below demostrate these problems, using string consisted of only CHAR_MAX symbol as grouping. In accordance with above description, such grouping string should be interpreted as absent of grouping at all. But the implementation behaves in different manner.

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.3.1.2

Example

//*********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;
}

Component

libstdc++

Environment

Architectures

x86, x86-64, IA64

Accepted

GCC Bugzilla 39168

Status

Fixed in gcc-4.4.0

[Home]