Anton Pevtsov wrote:
[...]
Here is another one possible issue:
As I understand 21.3.7.9, paragraph 4 the os.setstate() should be called
after os.width(0). In stdcxx width(0) is called after the setstate() and
if the exceptions mask is not ios_base::goodbit then width(0) will not
called. The Dinkumware STL and STLPort calls width (0) before
setstate().
I agree, although I note that GNU libstdc++ behaves the same as
stdcxx. I believe both implementations are incorrect.
FWIW, the standard is slightly inconsistent when it comes to these
things. I've sent an email to the committee's reflector proposing
to clean them up (see the attachment). I also put together a test
program exercising all formatted output functions (including the
string overload which isn't listed as one but should be) according
to the current requirements as well as according to the requirements
I propose. See http://people.apache.org/~sebor/width_test.cpp
incubator\stdcxx\trunk\include\ostream
// 21.3.7.9, p3 - defined here, declared inline in <string>
template<class _CharT, class _Traits, class _Allocator> inline
basic_ostream<_CharT, _Traits>&
operator<< (basic_ostream<_CharT, _Traits> & __strm,
const basic_string<_CharT, _Traits, _Allocator> &__str) {
_RW::__rw_insert (__strm, __str.data (), __str.length (),
__strm.width ()).width (0);
return __strm;
}
See the attached test, please.
What do you think about this?
Let's create an issue and fix it. The change shouldn't be too
difficult. I'll leave it up to you to propose a patch :)
Thanks
Martin
--- Begin Message ---
To: C++ libraries mailing list
Message c++std-lib-17244
A number of formatted input functions and all formatted output
functions are required to reset the stream's width to zero at
some point in their execution. Exactly when they are required
to do so differs depending on the overload. Here's a chart
that shows when each group of these functions is required to
call width(0):
Formatted extractors:
Bool: doesn't call width(0)
Arithmetic: doesn't call width(0)
Single char: doesn't call width(0)
Char array: after extracting the last character
String: after extracting the last character
Formatted inserters:
Bool: doesn't call width(0) in boolalpha mode
Arithmetic: before inserting the first character
Single char: before inserting the first character
Char array: after inserting the last character
String: after inserting the last character
Normally this is not detectable and doesn't cause any issues.
When it does come up and cause problems is in the presence of
exceptions.
For completeness here's how the three types of facets treat
width:
Facets:
money_put: after inserting the last character
num_put: before inserting the first character
time_put: doesn't call width(0)
This is a problem in user-defined inserters that use these facets.
I believe calling width() consistently in all cases is desirable
and propose that the arithmetic inserters (or rather the num_get
virtual members that do so) be changed to behave consistently with
the rest of the formatted I/O functions and reset width() to 0 after
successfully inserting all the characters. This change would also
make them consistent with money_put facet members. In addition,
I think we should also change time_put to reset the width to 0.
Martin
--- End Message ---