This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


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

Re: Linux vs. libio


Kevin Atkinson <kevinatk@home.com> writes:

> Maybe I am missing something but couldn't the io code in linux be
> written in pure C

I believe it is.

> with a few extensions to allow C++ wrapper classes to
> effectively use the io services.   Like say provide inline functions (or
> macros) to manipulate the buffer efficiently.

It is more complicated than that.  The point is *extensibility*
through jump tables (in C) or vtables (in C++).  The standard
C++ libary is a set of classes (and templates) that use
inheritance and virtual functions.

For exmaple, the C++ version of `getc' has an inline path that
is fast and similar to C:
        if (str->read_pointer < str->read_limit)
          return *str->read_pointer++;
        else
          return handle_slow_case(str);

So what we in GNU is use the *same* inline code for both C and C++.
I.e. the C++ methods and the C getc access the *same* read_pointer.

For C++, handle_slow_case(str) actually does a virtual function
call to a method which depends on the run-time type of (*str)
(which is not necessarily known at compile-time).  For example,
we may be reading from a file, a string, a socket, a wrapper
around readline, or an Emacs-style buffer.  In standard C,
there is only only kind of FILE, so we can call the appropriate
function directly.  However, glibc has long provided similar
extensible I/O as C++, but using jump tables of function pointers.
It makes sense to use the same format for those jump tables as
the C++ virtual function tables, hence some of the ugly macros
in the libio source.

One can write a C++ wrapper class (say stdiobuf) that implements the
C++ functionality, but uses the C stdio buffers.  The problem is that
this is slow, since you have to call handle_slow_case on every
character.  You can force that by setting read_pointer == read_limit
(for those streams that are aliased to stdio).  Alternatively, you can
make sure to use the same value of read_pointer for C FILEs and C++
filebufs.  However, then either you get extra overhead (indirection)
or you have to merge the data structures for C and C++.
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

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