Extending AsmPrinter

How so? It's entirely possible to use FILE*'s without virtual
methods: just don't use iostreams.

But you lose some flexibility. It may very well be a valid choice, but it
needs to be carefully considered. But see below for more on dynamic
vs. static polymorphism.

> What "overhead" are you talking about, specifically? I'm not sure
> what you're
> getting at here. All buffering necessarily has some overhead.

Buffering has overhead from copying data around. It doesn't matter
whether you do in by using stdio buffering or by building your own
buffers to avoid virtual method overhead.

Sure. But that has nothing to do with iostreams _per_se_.

>> How is this different than buffering done by stdio?
>
> It's in front of the virtual calls. So you only invoke virtual
> calls when the
> buffer is full. At that point, you're writing to the file cache at
> best or to
> disk at worst (or is that to the network?). A virtual call seems a
> small
> price to pay for the flexibility it provides.

How is that different than stdio?

The virtual calls provide the flexibility to do custom streambufs, which has
all sorts of nice encapsulation properties.

Now, if I were to redesign iostreams, I would try to turn that dynamic
polymorphism into static polymorphism. I think the ability to switch
streambufs at runtime is hardly ever used, so we really don't need virtual
calls.

But maybe we'd have to keep something around for the runtime flexibility to
satisfy any current needs. But I've certainly never seen a need for it in
real code. One thing I've learned over time is that inheritance and dynamic
polymorphism tends to be grossly overused. Most polymorphism is in fact
completely static. Some of this current bias towards dynamism reflects the
immaturity of template implementations in the late '90's. We're well beyond
that level of technology now, however.

In any event, the design I've chosen tries to approach the speed of static
polymorphism without redesigning the whole library.

> It also means developing new manipulators and possibly locale
> support if
> we want to use it for error messages and the like.

Manipulators and locales are two other really ugly things of
iostreams :slight_smile:

I haven't dealt with locales, but manipulators are very useful. What they
missed was standardizing a way to allow user-defined manipulators with
arguments. tr1::functions could help with that in any i/o redesign.

> What you're talking about is developing a new C++ I/O library,
> which is
> certainly a worthy goal, but one I'm not being paid to achieve. :slight_smile:

Fair enough.

Again, if a group (not just from llvm but crosscutting the C++ community) got
together to design a new I/O system I'd be all for it. But I think iostreams
gets a worse rap than it really deserves. Yes, there are things in there
that makes a modern C++ engineer cringe, but the basic concepts are sound.
Some implementations are better than others and this probably reflects areas
in which the standard could be improved to more easily get consistency across
vendors.

                                               -Dave

what you're
getting at here. All buffering necessarily has some overhead.

Buffering has overhead from copying data around. It doesn't matter
whether you do in by using stdio buffering or by building your own
buffers to avoid virtual method overhead.

Sure. But that has nothing to do with iostreams _per_se_.

I'm aware of that.

Now, if I were to redesign iostreams, I would try to turn that dynamic
polymorphism into static polymorphism. I think the ability to switch
streambufs at runtime is hardly ever used, so we really don't need virtual
calls.

Right.

Overall, go ahead and design your solution. Instead of making abstract arguments we can evaluate the final product and see if it is suitable for wider-spread use in LLVM.

-Chris

Yep, that's the best approach.

                                              -Dave