[sword-devel] 1.5.3 + optimizations

David White sword-devel@crosswire.org
20 Feb 2002 20:03:32 +1100


isalpha et. al. are entities found in C (they are usually implemented as
macros, not functions in C I believe). However, Sword is written in C++,
and isalpha et. al. are C++ functions; them happening to exist in C is
of little relevance, except for historical reasons, or to ease the
learning of C++ for those who are familiar with C.

In C++, the functions defined in <cctypes> (ctypes.h is a deprecated way
of expressing this header), should be found in the std namespace. That's
not to say all implementations do it that way, but that's the proper way
to do it. I understood gcc was becoming alot more standards compliant in
this regard starting with version 3, but I could be wrong about that.

I would also recommend that the C++-style versions of the cctypes
functions be used. They allow the specification of the locale in which
the function is going to perform. The C++ locale support is better than
in C, information on locales in C++ can be found at:
http://www.research.att.com/~bs/3rd_loc0.html (this is actually a
downloadable appendix to the book "The C++ Programming Language").

The case insensitive versions of the C-style string comparison functions
are not standard, or they may have differing names. BSD 4.4 defines case
insensitive string comparisons that are named strcasecmp and strncasecmp
for example, other implementations, such as Microsoft at one stage tend
to prepend non-standard function names with an underscore, so it might
be _stricmp or _strcasecmp.

I would not recommend using the "using namespace std;" declaration. It
is generally considered poor taste to import an entire namespace. Far
better to just import the names you want - "using std::strcmp;" for
example. In particular, the using statement should never be used at all
in a header file that is going to be #included by more than one source
file. It should *never ever* be used in a header file of a library; if I
want to use a library, I do not expect one of its headers to import
symbols for me that I don't intend to use.

The C++ string class does not supply case insensitive comparisons as
such, however the class is written with sufficient genericity in mind,
so that implementing case insensitive strings is very easy. Essentially,
std::string is not a class at all, but a convenient typedef for the very
flexible std::basic_string class. The definition of std::string looks
like this:

typedef std::basic_string<char, char_traits<char>, allocator<char> >
string;

The bit we are interested in is "char_traits". char_traits are simply a
structure which dictates the "traits" of the char - how they are
compared, and such. All we have to do to make a case insensitive string
is define our own case insensitive traits structure - we can derive it
from char_traits and just change a few things, and then define a case
insensitive string class:

typedef std::basic_string<char, insensitive_char_traits<char>,
allocator<char> > istring;

More information can be found on how to do this here:
http://www.gotw.ca/gotw/029.htm

Blessings,

David.

On Wed, 2002-02-20 at 02:37, Gregg Stubbendieck wrote:
> Hi all,
> 
> Hope you don't mind an interjection from out of nowhere.  I've only recently
> come across your project and am very intrigued about it.  I think that this
> project is about the best use of the open source concept that could be
> conceived.
> 
> isalpha(), et. al., are declared in <ctypes.h>.  They are C functions--not
> in std namespace.  This (compiling under 3.0.3) is the reason I subscribed
> to the devel mailing list.  In my experience, including ctypes.h in the
> offending source file fixes that problem just fine and I think you get to
> the link stage before the next problem arises.  My compiler, using gcc
> 3.0.3, was not able to find the case insensitive versions of the string
> functions (stricmp(), etc.).  I've never actually used the case insensitive
> versions of the string functions and am led to wonder whether they're part
> of the ANSI standard.  I got stuck there since it looks like a fix would
> require some research and code change.  I'm curious whether the C++ string
> class has the functions that are desired, otherwhise I would consider the
> regex library, which does apparently have the advantage of a POSIX standard.
> 
> As noted below, as long as there aren't name clashes between the namespaces
> in use, it's possible just to put a "using namespace std;" statement at the
> top of a pre-standard bit of code.  The problem then becomes conditionally
> including that statement depending on the vintage of your compiler.  This
> seems like a situation where autoconf and/or automake would be handy.  I
> have to believe that autoconf can generate a test for the presence of
> namespace std or not.  This solution might approach the desired elegance.
> Unfortunately, saying that, I've nearly reached the limits of my expertise
> on those tools.
> 
> The -march=XXX and -mcpu=XXX flags should only be necessary if you're cross
> compiling, right?  If I'm compiling for my system using a locally compiled
> version of the compiler (or at least one native to my processor) I should be
> able to leave those options off, I think.
> 
> Gregg
> 
> ----- Original Message -----
> From: "David White" <dave@whitevine.com>
> To: <sword-devel@crosswire.org>
> Sent: Tuesday, February 19, 2002 2:20 AM
> Subject: Re: [sword-devel] 1.5.3 + optimizations
> 
> 
> > This is likely because in C++, all C runtime functions (isalpha,
> > isdigit, strcmp, strncpy and so on and so forth) are meant to be in the
> > std namespace, rather than in the global namespace. So, you have to use
> > std::isalpha instead of isalpha (and likewise for all C runtime
> > functions).
> >
> > Many C++ compilers, including gcc didn't implement this for a long time.
> > gcc has only just implemented it in 3.0, and MSVC++ still doesn't,
> > although likely will in the next version.
> >
> > This is a fairly difficult problem to solve elegantly (Note that using
> > the declaration "using namespace std;" is *not* elegant :), since the
> > code will be expected to compile on both types of compilers (although
> > note that lots of older-style compilers have std:: as a synonym for ::,
> > so the newer solution should work with them anyway; however I don't
> > think this holds for MSVC++. A good article on the topic can be found at
> > http://www.gotw.ca/gotw/053.htm although it deals largely with code that
> > isn't expected to work on both kinds of compilers.
> >
> > Of course, the problem can largely be side-stepped by using C++-style
> > functions instead of C style functions, which are more typesafe and
> > generally better style (imho of course :) than their C equivalents. Of
> > course, some C-style functions such as those declared in ctype have no
> > C++ equivalent.
> >
> > Blessings,
> >
> > -David.
> >
> > On Tue, 2002-02-19 at 18:55, David Blue wrote:
> > > On Wednesday 13 February 2002 06:48 pm, you wrote:
> > > > Hello all,
> > > > If there is anything else pressing that anyone wants to get in, please
> > > > send me a patch soon, or suggest it here on the list and see if anyone
> > > > is willing to do it.
> > >
> > > Not so much as code that needs to go in but will 1.5.3 be compatible
> with
> > > gcc3? I've got a system that lets me swap back and forth between
> gcc3.0.3 and
> > > gcc2.96 and sword 1.5.2 refuses to compile under gcc3 it can't find the
> > > prototypes for the isalpha function or some such thing. I can produce
> the
> > > exact error if you need it. I know it's not just my system however,
> since it
> > > sucessfully compiles under gcc2.96 (though I can't compile chetah with
> gcc3
> > > if it is apparently ;_;) Oh, and in gcc3 the -m486 switch is deprecated
> and
> > > now uses -march=ix86 (x can be 3-6) or -mcpu=ix86.
> >
> >
> >
>