Why C++ Templates (and STL) Are Bad

(started by Brian Wilson, 2/24/05, last updated 5/30/05)


(Read a personal description of Backblaze here.)

What is this Web Page: C++ programmers fall into two camps, one camp that just can't imagine life without STL and use it on every 3rd line of C++ code they write, and those of us that try to stay entirely away from it.  I wanted to create this webpage to explain why I stay away from using any STL.  Also be sure to read other people's comments (both supporting and dissenting opinions on STL) here.

About me: I started programming 'C' in 1986, and I have considered myself a full time 'C++' programmer since late 1994 when I started work in the InPerson Video Conferencing group at Silicon Graphics which exclusively used C++.  My first experience with STL and templates was around 1995 or 1996 at SGI, and then over the years STL has become a more and more common of most projects I work on.  I debug issues every day that involve STL code.  These are not bugs in STL, but in the way another programmer called it incorrectly, or possibly the STL is just there hanging around the actual bug which is in regular C++.

One Issue: STL is Poorly Supported By Developer Tools: Below is a screenshot of real MailFrontier C++ source code I am working with today (2/24/05).  It is shown in Microsoft Visual Studio .Net (also known as Visual Studio 7.0).  The source code is parsing XML of a settings file that configures our product.  Visual Studio has a nice feature where if you hover your mouse pointer over any C++ method, it will show you the syntax of that method.  Two screenshots are taken, the top one is when I hover my mouse pointer over the STL std::string's "compare()" method.  The screenshot below that one is when I hover my mouse pointer over MlfString::Equals(), MlfString" which is a very simple C++ class that we created all in Native C++ (no STL) that has a few simple methods on it such as "Equals()" and "Append()".  Notice how grotesque and completely unusable the STL support is in the development environment, compared with when you write regular straight-forward C++.

In the screen shots above, the Visual Studio environment has gone completely nuts over STL.  Now I've heard programmers saying this means Microsoft Visual Studio has issues, and that STL is great, but I haven't seen anything better in Linux, Solaris, HP-UX, A/UX, SGI's IRIX, Apple Macintosh (CodeWarrior) or any of the other development platforms I've worked on.  STL always seems to destroy your friendly development environment that helps you debug issues quickly and efficiently if the original programmer had used straight-forward C++.

 

Issue #2: STL API Syntax is Unclear, the Designers Had No Taste There are APIs that are clear and the designers "get it", and there are APIs that are totally unclear, ambiguous, and the designers seem like they have never programmed before.  STL falls into the latter camp, the designers had bad taste and little or no experience at defining APIs.  I'm not talking about "concepts" or "implementation", STL is reasonably fast and conceptually pure.  It just isn't brain-dead simple and clear from the method and class and concept names what anything does.  This isn't fatal, but it does make STL harder for people to use it.  Take a specific example: Iterators.  If you want a "read-only-iterator" to read some values out of a data structure you use an "InputIterator", and if you want a "write-only-iterator" you use a "OutputIterator".  Let's just pause there and let that sink in.  Why weren't they called "ReadOnlyIterator" and "WriteOnlyIterator"?  It's just plain bad API taste to use unclear, ambiguous terms.  The very words "Input" and "Output" are even reversed from what might make sense in this case!  How bad can you get? 

Take one more example, something extremely simple: the STL string class (horrible API) and Java's "String" class which has a very clear and easy to use API.  One of the most common things you want to do with a string is know whether it starts or ends with a certain sequence of characters.  Here is an example in Java:

    String filePath = "/tmp/downloaded.exe";
    if ((filePath.startsWith("/tmp")  && (filePath.endsWith(".exe"))
        // fits the pattern.

The above is clear, obvious code, even if somebody has never written Java before you know exactly what it does.  The "String.startsWith()" and "String.endsWith()" APIs are perfect.  Now contrast that with the same code in STL below:

    std::string filePath = "/tmp/downloaded.exe";
    std::string::size_type startPos = filePath.find("/tmp", 0);   // the "zero" means start from beginning
    std::string::size_type endPos = filePath.rfind(".exe", filePath.size() - 1);  // search from back to see if it ends in ".exe"
    if ((startPos == 0) && (endPos == filePath.size() - 4))
        // fits the pattern.

That's hideous!  And notice I put in comments to help the understanding, while the Java didn't require any comments.  And what happens if I get the constants wrong, like the "-1" and the "-4"?  STL is bug-free, but with such a lousy API it encourages the programmer to make mistakes using it.  If I was looking for a bug and stumbled across this code, I would have to examine it VERY closely and waste valuable time to make sure the original programmer got all the constants correct.  Not to mention that without the comments I wouldn't understand it.

Issue #2: STL Writes Fast, And Debugs Slow: More to come.

Issue #3: STL Encourages (Lures?) Programmers to Use Very Complex Data Structures: There is a saying regarding safety in backcountry skiing: "Earn your turns".  What it means is that it is really fun to ski down steep mountains filled with snow, but you need to expend the effort to walk up the slope first and examine the snow at every step to make sure it is safe (avalanche free).  The idea of walking up a large mountain also discourages a lot of "irresponsible and inexperienced" people from doing it, thus saving their lives.

In programming, I have the same philosophy.  STL gets beginner programmers in trouble VERY fast.  In stead of figuring out how to solve a problem with a simple data structure, or without any data structures at all, STL offers full-tilt-grandiose psychotically complex data structures at the mere typing of one line.  If a programmer will have to spend 10 minutes writing their own linked list, they will make sure it is as simple as it can possibly be.  But with STL, it takes no time at all to have a linked list of pairs of hash tables.  Unfortunately, 9 times out of 10 there was a much simpler approach where the programmer would not have needed such a crazy and complex data structure.  Here is an example from our code at MailFrontier that another engineer stumbled across:

If you look at the example above, it is a case of STL gone nuts.  In one line "forceUpates" is a very complex data structure, but it turns out this data structure was totally unnecessary, all the code needed to do was loop over a few files and set a flag.  This example also shows how subtle and incomprehensible STL compiler problems are, can you see the error in the syntax?  Hint: it is one space that needs to be added or the code will not build.

 

Feedback and Comments From Other People: Some people have commented on this web page, you can read their comments here.  Some of these people I know, others I do not know.  Some are in favor of STL, some do not like it.  Feel free to send me more comments and I can post them.

 

 


(Read a personal description of Backblaze here.)

Click Here to Return to Random Stuff