Title
Improper use of traits_type::length()
Status
cd1
Section
[ostream.inserters.character]
Submitter
Dietmar Kühl

Created on 1999-07-20.00:00:00 last changed 171 months ago

Messages

Date: 2010-10-21.18:28:33

Rationale:

We have five separate cases. In two of them we can use the user-supplied traits class without any fuss. In the other three we try to use something as close to that user-supplied class as possible. In two cases we've got a traits class that's appropriate for char and what we've got is a const signed char* or a const unsigned char*; that's close enough so we can just use a reinterpret cast, and continue to use the user-supplied traits class. Finally, there's one case where we just have to give up: where we've got a traits class for some arbitrary charT type, and we somehow have to deal with a const char*. There's nothing better to do but fall back to char_traits<char>

Date: 2010-10-21.18:28:33

[ Kona: changed "where n is" to " where n is the number that would be computed as if by" ]

Date: 2010-10-21.18:28:33

[ Santa Cruz: Matt supplied new wording ]

Date: 2010-10-21.18:28:33

Proposed resolution:

Change [ostream.inserters.character] paragraph 4 from:

Effects: Behaves like an formatted inserter (as described in lib.ostream.formatted.reqmts) of out. After a sentry object is constructed it inserts characters. The number of characters starting at s to be inserted is traits::length(s). Padding is determined as described in lib.facet.num.put.virtuals. The traits::length(s) characters starting at s are widened using out.widen (lib.basic.ios.members). The widened characters and any required padding are inserted into out. Calls width(0).

to:

Effects: Behaves like a formatted inserter (as described in lib.ostream.formatted.reqmts) of out. After a sentry object is constructed it inserts n characters starting at s, where n is the number that would be computed as if by:

  • traits::length(s) for the overload where the first argument is of type basic_ostream<charT, traits>& and the second is of type const charT*, and also for the overload where the first argument is of type basic_ostream<char, traits>& and the second is of type const char*.
  • std::char_traits<char>::length(s) for the overload where the first argument is of type basic_ostream<charT, traits>& and the second is of type const char*.
  • traits::length(reinterpret_cast<const char*>(s)) for the other two overloads.

Padding is determined as described in lib.facet.num.put.virtuals. The n characters starting at s are widened using out.widen (lib.basic.ios.members). The widened characters and any required padding are inserted into out. Calls width(0).

Date: 1999-07-20.00:00:00

Paragraph 4 states that the length is determined using traits::length(s). Unfortunately, this function is not defined for example if the character type is wchar_t and the type of s is char const*. Similar problems exist if the character type is char and the type of s is either signed char const* or unsigned char const*.

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg1736
2010-10-21 18:28:33adminsetmessages: + msg1735
2010-10-21 18:28:33adminsetmessages: + msg1734
2010-10-21 18:28:33adminsetmessages: + msg1733
1999-07-20 00:00:00admincreate