Undefined behavior in locale_facets.tcc
Doug Gregor
dgregor@apple.com
Wed Jul 2 21:52:00 GMT 2003
Several routines in locale_facets.tcc use iterators passed to them in a
way that invokes undefined behavior. The affected routines include:
num_get::_M_extract_float
num_get::_M_extract_int
money_get::do_get
time_get::_M_extract_num
time_get::do_get_year
All of these have a loop that contains one or more occurrences of the
expression *(++__beg), which invokes undefined behavior when ++__beg
returns a past-the-end iterator (they can't be dereferenced).
However, we've never seen failures because:
1) __beg is always an istreambuf_iterator (22.2.5/1, and others like
it, say we're allowed to assume this).
2) the libstdc++ istreambuf_iterator dereference operation returns
traits_type::to_char_type(traits_type::eof()) when the iterator is
past-the-end. This is an (undocumented) extension; 24.5.3/2 says the
result is undefined.
The end result is that the code works for our istreambuf_iterators
because of the extension, but won't necessary work for anything else.
Is there a policy regarding reliance on libstdc++ extensions within
libstdc++ code? This is especially important for me because under debug
mode the standard-specified semantics are checked, so the use of the
extension causes the debug mode to flag an error. How do we want to
work around this problem? I/we could:
1) Rewrite the offending code to not use the extension.
2) Hide the past-the-end check for istreambuf_iterator behind
_GLIBCPP_DEBUG_PEDANTIC (which flags errors at uses of extension
semantics).
3) Turn off checking around these blocks of code.
It's likely that this issue will come up again, so I would prefer to
have a policy in place that says what we should do.
Doug
More information about the Libstdc++
mailing list