Details

[Home]

Issue of the Implementation # S0711

Brief

num_put<>::do_put(bool) performs 'internal' padding incorrectly when boolalpha==true

Detailed Description

The description of num_put<>::do_put(bool) function states (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& np = use_facet<numpunct<charT> >(loc);
string_type s = val ? np.truename() : np.falsename();
and then insert the characters of s into out.


Note: "put" instead of "do_put" in the function's signature is a misprint. See the details here. End Note.

It is not specified how exactly the insertion the characters of s into out iterator is performed. It seems that the padding of the string (filling it with extra characters to bring it to the required length) is done the same way as for the other functions from num_put<>::do_put() family, namely (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), however, should output a string that in general is not a string representation of some number. It makes no sense for a string that can be arbitrary to process the sign symbols, "0x" or "0X" in a different way than its other substrings. That means, the 'internal' flag should be functionally equivalent to 'right' ("pad before") in this case.

This is exactly the way the operator for inserting sequences of symbols into a stream (operator<< for const charT*) is implemented. Although the description of padding in this case (27.6.2.5.4, p2) refers to the description of num_put<>::do_put, in practice the 'internal' flag should be functionally equivalent to 'right' in this case, which makes sense.

However, the implementation of num_put<>::do_put(bool) performs 'internal' padding not like operator<< for sequences of characters but rather the same way as the other functions from num_put<>::do_put family: it inserts fill symbols between the 'sign' or "0x"/"0X" and the rest of the string.

For example, the program below outputs "-  no-" while it should output "  -no-".

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

Example

#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;
}

Component

libstdc++

Accepted

GCC Bugzilla 38196

Status

Fixed in gcc-4.4.0

[Home]