This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: _M_fill initialization in basic_ios::init


On Fri, Dec 07, 2001 at 10:56:51AM +0000, Richard Burkert wrote:
> Nathan Myers wrote:
>  >I would not expect constructing a stream to fail, because construction
>  >is not defined in the standard to depend on any facet members.  I would
>  >expect any formatted i/o operation to fail, though.  Crashing is a poor
>  >way to fail in that case, but probably not explicitly nonconforming.
> 
> Right, I didn't expect that I would be able to use formatted i/o,
> but I thought I should still be able to construct and use a stream
> without any locale facets as long as i stuck to raw input and output
> operations.

You should be able to, but you shouldn't want to.

> You're right that a streambuf is really all I want then,
> thanks for pointing that out, I just had the dumb notion that stream-
> bufs were meant to be used just with streams and not independently.

That would be like saying FILE* is meant to be used only with printf()
and scanf(), and avoiding putc(), getc(), fread(), and fwrite().

> But that aside, when you say construction isnt defined to depend on
> any facet members, does that mean it's wrong to depend on one or
> just that the standard doesn't say one way or another?  Because
> practically it does depend on ctype if you need to default the fill
> character to widen(' '). I don't have the standard, I don't know
> what it says about that.

The standard doesn't say that construction depends on calling widen,
so I think it's wrong for the constructor to call widen if it might
not be there.  If you call something that is (e.g.)  obliged to
construct a sentry that eats whitespace, it needs ctype, so a
ctype had better be there at that point.

Dealing with this all makes iostream operations a little less efficient,
because each format/parse operation has to check if the values it needs
have been cached yet, instead of just assuming they were set up at 
construction or imbue time.

Anyway, it does little good to cache the facets themselves; they're
cheap to get.  What takes time is all those virtual function calls
to extract the details, and that's what should be cached.  I had 
apparatus in place to cache all that stuff, but it appears to have 
been stripped out.  If you look at early snapshots (maybe 2.90.4?) 
you can see what I had in mind (and in code).

The stream can also take advantage of "prior knowledge", such as 
preloading the cache with "C" locale values, and leaving it marked
valid if that's what the stream actually ends up as.  Also, you can
share the cache among all streams that share the same locale.
There are lots of optimization opportunities, with the end result
that C++ i/o can be as fast as, or faster than, C i/o.  (Note that
C++ has the advantage that it knows the type already, where C has to 
interpret a format string.  That's assuming you don't turn around 
and call printf, throwing the information away.)

Nathan Myers
ncm at cantrip dot org


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]