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
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]