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]

Re: correct "C" headers, higher priority


On Fri, 01 Jun 2001, Benjamin Kosnik wrote:
> > I've been trying to figure out how to build the <c...> headers by leveraging the
> > C library headers.  Perhaps this is entirely the wrong approach.  Maybe what
> > should be done is implement the C++ library on top of the C library, but keep
> > the headers discrete.  For example, std::strlen() would be declared extern in
> > <cstring>, and the definition of that finction in some .cc file would simply
> > forward the ::strlen() function from the underlying C library.  Forgive me if
> > this is too obvious, but none of the C++ standard libraries I've examined take
> > this approach (I don't have access to most proprietary ones).
> 
> I'm not quite sure I follow you. Could you work up an example for just 
> strchr?

I've ben doing that:  simple things like <cstring> and <cctype> are no problem
at all.  Then I tried <clocale>.  It's the data structures that break things: 
struct lconv, for example.  I shudder at the thought of <cstdio>.

As a fix for the current <cstring> malaise, this idea would still work, since
there are no PODs or C macros required in that header.

Here's an exemplar description.  I can work up a patch at home tonight to
better describe what I mean, if it would help.

in include/c_std/bit/std_cstring.h, the #include <string.h> would be removed,
and strchr would be declared extern thusly.

#undef strchr

namespace std
{
    ....
    extern const char* strchr(const char*, int);
    extern         char* strchr(char*, int);
    ....
}

In a new file, say src/cstring.cc, the functions would be defined like this.

// pull in the C library declarations
#include <string.h> 

// local forwarding functions to capture builtins, redefined names, etc
namespace
{
    inline char*
    clib_strchr(const char* __s, int _n)
    { return strchr(__s, __n); } 
}

// just in case...
#undef strchr

// the official libstdc++ definitions
namespace std
{
    const char*
    strchr(const char* __s, int __n)
    { return clib_strchr(__s, __n); }

    char*
    strchr(char* __s, int __n)
    { return clib_strchr(__s, __n); }
}


Note that when compiled with inlining enabled, the clib_* functions just
disappear.  Also note that no const_casts are necessary anywhere since
there's no overloading on constness.

You can include <cstring> and <string.h> in the same source file, and order
doesn't seem to matter (which I don't understand, but it worked for <cctype>,
which I know defines macros).  If you include just <cstring>, there's no global
namespace pollution and "using namespace std" works without conflicts, which
fixes the original PR that started this off.  The price is an extra function
call and less opportunity for inlining.

We could provide our own <string.h> (not included when building cstring.cc
above) that would conform to Appendix D, which would guarantee
&strchr = &std::strchr.

I do have problems with certain functions the compiler provides as builtins.
Everything works with -fno-builtin, but I don't think that's something we
should require an end user to do.  Small thing, deal with it later.

Perhaps this approach for <cstring> and <cmath> (?) while leaving some of
the more onerous headers (which no one has complained about) for later will
get a better 3.0 out the door sooner.


Stephen M. Webb


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