This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: _M_fill initialization in basic_ios::init
Hi sorry for the lag in response, my computer hasn't been in a
usable state for the last week. Anyway skip to the bottom if you
just want the test code.
Paolo Carlini wrote:
>For instance, Langer/Kreft (0-201-18395-1), which I usually trust for
iostreams
>and locale issues (and is much more easier to read than the standard ;-)
>explicitly says at the beginning of chapter 5 that ctype is a
*standard* facet,
>not a user-defined one, so it is "automatically contained in every
locale".
Well it is a standard facet in that it's part of the set group
of character facets predefined by the standard c++ library, but
I don't think it's mandatory for two reasons that I can think
of. The first is just the fact that I don't think streams at
their core should have to have anything to do with language or
locales, since they can be useful for other types of data. So
requiring locale facets for all stream element types would be
pretty defeating for that whole area of stream application, or
at the very least annoying, since you would have to manually
define facets that you'd never actually use just to get the
standard iostreams to work on a certain data type. The ctype
facet is for converting a stream element to and from char, I
don't see at all why that should be a requirement for every
type of stream element. The second reason is that the exist-
ing libstdc++ code even indicates that all of the facets are
optional. Take a look at _M_cache_facets from bits/basic_ios.tcc
again:
template<typename _CharT, typename _Traits>
void
basic_ios<_CharT, _Traits>::_M_cache_facets(const locale& __loc)
{
if (has_facet<__ctype_type>(__loc))
_M_ios_fctype = &use_facet<__ctype_type>(__loc);
// Should be filled in by ostream and istream, respectively.
if (has_facet<__numput_type>(__loc))
_M_fnumput = &use_facet<__numput_type>(__loc);
if (has_facet<__numget_type>(__loc))
_M_fnumget = &use_facet<__numget_type>(__loc);
}
It only caches each facet (note ctype first) -if- the locale
supports that facet for whatever the stream element type. That's
what it looks like to me at least, and at any rate it might not
initialize _M_ios_fctype yet it calls a function from _M_ios_fctype
no matter what (widen in init like i said before), so that
doesn't seem right. If you wanted to require the ctype facet
maybe assert that in _M_cache_facets instead of just conditionally
initializing something which is later used unconditionally and
letting it crash in the cases where it didnt have the facet.
I don't know, maybe even though there's contradictory code in
basic_ios, they wanted all locales to support even the sort of
null generic ctype so that wouldn't ever be a problem. Then the
problem would be somewhere in the ctype or has_facet definitions
in bits/locale_facets.* Either way the code in basic_ios could
use some clarifying I think.
>So, please, come up with a self-contained seg-faulting testcase: it
will help
>focusing the real problem here.
Here you go:
#include <sstream>
int main () {
std::basic_stringstream<int> test;
return 0;
}
ctype only has predefined specializations for char and wchar_t,
so int just gets the generic version which apparently doesn't
do it for whatever locale i'm in. See how it goes for you.
Rich