views:

1510

answers:

20

Recently, I've got a dangerous idea into my head after reading this blog post. That idea can be expressed like this:

I don't need most of what the C++ standard library offers. So, why don't I implement a less general, but easier to use version?

As an example, using the STL spits out reams of incomprehensible and mangled compiler errors. But, I don't care about allocators, iterators and the like. So why don't I take a couple of hours and implement an easy to use linked list class, for example?

What I'd like to know from the StackOverflow community is this: what are the dangers, possible disadvantages and possible advantages to "rolling my own" for most of the existing functionality in C++?

Edit: I feel that people have misunderstood me about this idea. The idea was to understand whether I could implement a very small set of STL functionality that is greatly simplified - more as a project to teach me about data structures and the like. I don't propose re-inventing the entire wheel from the ground up, just the part that I need and want to learn about. I suppose what I wanted to figure out is whether the complexity of using the STL warrants the creation of smaller, simpler version of itself.

Re-using boost or similiar.

Most of what I code is for University and we're not allowed to use external libraries. So it's either the C++ standard library, or my own classes.

Objectivity of this question.

This question is not subjective. Nor should it be community Wiki, since it's not a poll. I want concrete arguments that highlight one advantage or one disadvantage that could possibly occur with my approach. Contrary to popular belief, this is not opinion, but based on experience or good logical arguments.

Format.

Please post only one disadvantage or one advantage per answer. This will allow people to evaluate individual ideas instead of all your ideas at once.

And please...

No religious wars. I'm not a fan boy of any language. I use whatever's applicable. For graphics and data compression (what I'm working on at the moment) that seems to be C++. Please constrain your answers to the question or they will be downvoted.

+7  A: 

Disadvantage: you may spend more time debugging your class library than solving whatever university task you have in front of you.

Advantage: you're likely to learn a lot!

Eyvind
Good answer, but can you factor this into two answers?
fluffels
+1  A: 

what are the dangers, possible disadvantages and possible advantages to "rolling my own" for most of the existing functionality in C++?

Can you afford and possibly justify the amount of effort/time/money spent behind reinventing the wheel?

Re-using boost or similiar.

Rather strange that you cannot use Boost. IIRC, chunks of contribution come in from people related to/working in universities (think Jakko Jarvi). The upsides of using Boost are far too many to list here.

On not 'reinventing the wheel'

Disadvantage: While you learn a lot, you also set yourself back, when you come to think of what your real project objectives are.

Advantage: Maintenance is easier for the folks who are going to inherit this.

dirkgently
Don't ask me... My University professors are infected with "do it yourself" syndrome. Which may or may not be a good idea!
fluffels
How is maintenance easier when reinventing the wheel? Won't that just mean more code to maintain, and fewer people familiar with it?
jalf
Schools should have "do it yourself" syndrome; doing things is how you learn.
Giovanni Galbo
@jalf: It's 'not' reinventing the wheel, please check ;-)
dirkgently
@Giovanni Galbo: If I started off by implementing <stdio.h> to use printf, I wouldn't have learnt a lot of C. Scale it to a much bigger proportion.
dirkgently
Have a look at the code for printing floating point numbers and tell me you can not learn from the stdio module ;-)
James Dean
I am not saying you cannot learn. Re-read my post.
dirkgently
+19  A: 

Advantages: eating your own dogfood. You get exactly what you do.

Disadvantages: eating your own dogfood. Numerous people, smarter than 99 % of us, have spent years creating STL.

Joonas Pulakka
Good answer, but can you factor this into two answers?
fluffels
I've been lucky enough to attend some of the standard committee meetings. I would second this sentiment with one modification, the percentage is probably closer to 99.99%!!! There are some very very clever people there.
Richard Corden
+4  A: 

Disadvantage : IMHO, reimplimenting tested and proven libraries is a rabit hole which is almost garanteed to be more trouble than it's worth.

John MacIntyre
+40  A: 

Disadvantage: no one but you will use it.

Advantage: In the process of implementing it you will learn why the Standard Library is a good thing.

anon
I though about that advantage a lot. I actually think that might be worth the whole excersize!
fluffels
Can you factor this into two answers?
fluffels
Yes, and you will come to this realization only as you stand - alone, in tears - on the shore line, watching as the good ship STL sails your class mates to the isle of project delivery . . . and your own pitiful exercise in boat building lies at the bottom of the lagoon. Don't do it bud
Binary Worrier
Worrier - You're assuming this is for a project, rather than for the sake of learning.For the sake of learning, it's probably the most educational approach. It's just also the most time consuming.
Adam Luchjenbroers
+12  A: 

I suggested you learn why:

using the STL spits out reams of incomprehensible and mangled compiler errors

first

Ben Reeves
I just want to be able to read the compiler messages! I don't really want to know why they're unreadable.
fluffels
Try this script which translates STL compiler warnings into human readable form: http://www.bdsoft.com/tools/stlfilt.html
Gilad Naor
Hey thanks! That'll be a huge help! I wish I could up-mod comments :)
fluffels
Or start reducing the thing with an editor. The messages I've seen have typically been overcomplicated because of the verbiage.
David Thornley
+2  A: 

Disadvantage : You're university course is probably laid out like this for a reason. The fact that you are irritated enough by it (sarcasm not intended), may indicate you are not getting the paridigm, and will benefit a lot when you have a paradigm shift.

John MacIntyre
I'm not sure I understand. What do you mean by "You're university course is probably laid out like this for a reason."?
fluffels
@fluffels-I would assume that in designing your course, some thought went into what to cover in order to cover specific training(?) goals. So STL, is probably there to cover a goal ... possibly for no other reason than to expose you to one of the most popular libraries in programming.
John MacIntyre
Well... this is an honours level course. I doubt that was their objective. I think it's just an unfortunate side effect.
fluffels
@fluffels-Yeah, well, I didn't see that
John MacIntyre
+1  A: 

Advantage

If you look into MFC, you'll find that your suggestion already is used in productive code - and has been so for a long time. None of MFC's collection classes uses the STL.

Thanks! At last, a redemptive answer :) Could you perhaps just add an advantage or something to this answer?
fluffels
The fact that none of MFC's collection classes uses the C++ standard library might have more to do with it predating both the widespread adoption of the STL and the MS compilers ability to compile it in its entirety.
Timo Geusch
You certainly have a point there. It might well be the reason. Perhaps, though, they just didn't like STL's naming conventions, how its containers looked in the debugger's watch window or their allocation pattern...
The MFC were designed for a different reason, and used its own collection classes because it needed something, and the STL wasn't even standardized until six years later. The MFC would be better off using standard containers etc., but that would be an incredible compatibility headache.
David Thornley
+1  A: 

Why don't you take a look at existing C++ libraries. Back when C++ wasn't quite as mature, people often wrote their own libraries. Have a look at Symbian (pretty horrible though), Qt and WxWidgets (if memory serves me) have basic collections and stuff, and there are probably many others.

My opinion is that the complexity of STL derives from the complexity of the C++ language, and there's little you can do to improve on STL (aside from using a more sensible naming convention). I recommend simply switching to some other language if you can, or just deal with it.

TrayMan
+3  A: 

Another Disadvantage:

If you want to get a C++ job when you're finished with University, most people who would want to recruit you will expect that you are familiar with the Standard C++ library. Not necessarily intimately familiar to the implementation level but certainly familiar with its usage and idioms. If you reimplement the wheel in form of your own library, you'll miss out on that chance. This is nonwithstanding the fact that you will hopefully learn a lot about library design if you roll your own, which might earn you a couple of extra brownie points depending on where you interview.

Timo Geusch
Nah, no sane employer expects a new graduate to know a language and its libraries inside out. Degrees are for learning principles. You learn libraries on the job.
slim
I (partially) disagree. If I get the resume for someone straight out of university and it states that they had done C++ programming, I would expect at least basic familiarity with the core language libraries. Not inside out, granted.
Timo Geusch
+8  A: 

There is something you can do about the cryptic compiler STL error messages. STLFilt will help simplify them. From the STLFilt Website:

STLFilt simplifies and/or reformats long-winded C++ error and warning messages, with a focus on STL-related diagnostics (and for MSVC 6, it fully eliminates C4786 warnings and their detritus). The result renders many of even the most cryptic diagnostics comprehensible.

Have a look here and, if you are using VisualC, also here.

Adrian Grigore
+3  A: 

Disadvantage: reimplementing all of that well (that is, at a high level of quality) will certainly take a number of great developers a few years.

But if you have a number of great develoeprs and a few years, please do! :)

romkyns
+51  A: 

So, why don't I implement a less general, but easier to use version?

Because you can't. Because whatever else you might say about C++, it is not a simple language, and if you're not already very good at it, your linked list implementation will be buggy.

Honestly, your choice is simple:

Learn C++, or don't use it. Yes, C++ is commonly used for graphics, but Java has OpenGL libraries too. So does C#, Python and virtually every other language. Or C. You don't have to use C++.

But if you do use it, learn it and use it properly.

If you want immutable strings, create your string as const.

And regardless of its underlying implementation, the STL is remarkably simple to use.

C++ compiler errors can be read, but it takes a bit of practice. But more importantly, they are not exclusive to STL code. You'll encounter them no matter what you do, and which libraries you use. So get used to them. And if you're getting used to them anyway, you might as well use STL too.

Apart from that, a few other disadvantages:

  • No one else will understand your code. If you ask a question on SO about std::vector, or bidirectional iterators, everyone who's reasonably familiar with c++ can answer. If you ask abut My::CustomLinkedList, no one can help you. Which is unfortunate, because rolling your own also means that there will be more bugs to ask for help about.
  • You're trying to cure the symptom, rather than the cause. The problem is that you don't understand C++. STL is just a symptom of that. Avoiding STL won't magically make your C++ code work better.
  • The compiler errors. Yes, they're nasty to read, but they're there. A lot of work in the STL has gone into ensuring that wrong use will trigger compiler errors in most cases. In C++ it's very easy to make code that compiles, but doesn't work. Or seems to work. Or works on my computer, but fails mysteriously elsewhere. Your own linked list would almost certainly move more errors to runtime, where they'd go undetected for a while, and be much harder to track down.
  • And once again, it will be buggy. Trust me. I've seen damn good C++ programmers write a linked list in C++ only to uncover bug after bug, in obscure border cases. And C++ is all border cases. Will your linked list handle exception safety correctly? Will it guarantee that everything is in a consistent state if creating a new node (and thereby calling the object type's constructor) throws an exception? That it won't leak memory, that all the appropriate destructors will be called? Will it be as type-safe? Will it be as performant? There are a lot of headaches to deal with when writing container classes in C++.
  • You're missing out on one of the most powerful and flexible libraries in existence, in any language. The STL can do a lot that would be a pain even with Java's giant bloated class library. C++ is hard enough already, no need to throw away the few advantages it offers.

I don't care about allocators, iterators and the like

Allocators can be safely ignored. You pretty much don't even need to know that they exist. Iterators are brilliant though, and figuring them out would save you a lot of headaches. There are only three concepts you need to understand to use STL effectively:

  • Containers: You already know about these. vectors, linked lists, maps, sets, queues and so on.
  • Iterators: Abstractions that let you navigate a container (or subsets of a container, or any other sequence of value, in memory, on disk in the form of streams, or computed on the fly).
  • Algorithms: Common algorithms that work on any pair of iterators. You have sort, for_each, find, copy and many others.

Yes, the STL is small compared to Java's library, but it packs a surprising amount of power when you combine the above 3 concepts. There's a bit of a learning curve, because it is an unusual library. But if you're going to spend more than a day or two with C++, it's worth learning properly.

And no, I'm not following your answer format, because I thought actually giving you a detailed answer would be more helpful. ;)

Edit:

It'd be tempting to say that an advantage of rolling your own is that you'd learn more of the language, and maybe even why the STL is one of its saving graces.. But I'm not really convinced it's true. It might work, but it can backfire too.

As I said above, it's easy to write C++ code that seems to work. And when it stops working, it's easy to rearrange a few things, like the declaration order of variables, or insert a bit of padding in a class, to make it seemingly work again. What would you learn from that? Would that teach you how to write better C++? Perhaps. But most likely, it'd just teach you that "C++ sucks". Would it teach you how to use the STL? Definitely not. A more useful approach might be utilizing the awesome power of StackOverflow in learning STL the right way. :)

jalf
+1: one of those few answers that I could could use my daily vote allocation on, but unfortunately can only +1 once. A truely excellent answer, the correct answer, and in fact the only answer to the posters problem. Well done mate.
Binary Worrier
+1 (padding added)
Nemanja Trifunovic
Excellent answer. Making this accepted. You make some very good points. Rest assured, I do "understand C++" (as much as anyone can), it's just that I lament it's overly complex nature sometimes.
fluffels
C++ is complex, but the library does its best to make it easy to use. You or I are unlikely to do any better.
David Thornley
Good answer. Only reason for making one is the teaching experience.
Jonas
Best SO answer ever! Best one that I have read anyway :-)
Chris Huang-Leaver
A: 

STL is very complex because it needs to be for a general purpose library.

Reasons why STL is the way it is:

  • Based on interators so standard algorithms only need a single implementation for different types of containers.
  • Designed to behave properly in the face of Exceptions.
  • Designed to be 'thread' safe in multi threaded applications.

In a lot of applications however you really have enough with the following:

  • string class
  • hash table for O(1) lookups
  • vector/array with sort / and binary search for sorted collections

If you know that:

  • Your classes do not throw exceptions on construction or assignment.
  • Your code is single threaded.
  • You will not use the more complex STL algorithms.

Then you can probably write your own faster code that uses less memory and produces simpler compile/runtime errors.

Some examples for faster/easier without the STL:

  • Copy-on-Write string with reference counted string buffer. (Do not do this in a multi-threaded environment since you would need to lock on the reference count access.)
  • Use a good hash table instead of the std::set and std::map.
  • 'Java' style iterators that can be passed around as a single object
  • Iterator type that does not need to know the type of the container (For better compile time decoupling of code)
  • A string class with more utility functions
  • Configurable bounds checking in your vector containers. (So not [] or .at but the same method with a compile or runtime flag for going from 'safe' to 'fast' mode)
  • Containers designed to work with pointers to objects that will delete their content.
James Dean
I'd be surprised, actually. The STL is also usually highly optimized.
David Thornley
I beat the STL and I wasn't even trying to write an optimized library.
dicroce
+3  A: 

Disadvantage:

You're introducing a dependency on your own new library. Even if that's sufficient, and your implementation works fine, you still have a dependency. And that can bite you hard with code maintenance. Everyone else (including yourself, in a year's time, or even a month's) will not be familiar with your unique string behavior, special iterators, and so on. Much effort will be needed just to adapt to the new environment before you could ever start refactoring/extending anything. If you use something like STL, everyone will know it already, it's well understood and documented, and nobody will have to re-learn your custom throwaway environment.

SPWorley
A good answer. Just using the STL will have the advantage of being generic knowledge.
fluffels
+7  A: 

I think you should do it.

I'm sure I'll get flambayed for this, but you know, every C++ programmer around here has drunk a little too much STL coolaid.

The STL is a great library, but I know from first hand experience that if you roll your own, you can:

1) Make it faster than the STL for your particular use cases. 2) You'll write a library with just the interfaces you need. 3) You'll be able to extend all the standard stuff. (I can't tell you how much I've wished std::string had a split() method)...

Everyone is right when they say that it will be a lot of work. Thats true.

But, you will learn a lot. Even if after you write it, you go back to the STL and never use it again, you'll still have learned a lot.

dicroce
Great answer :) I was certain I would get flambayed for even asking the question!
fluffels
Not *every* programmer here. :-) The STL is great -- but if I hadn't written my own versions before it came out, I wouldn't understand the design decisions involved, or why to use certain containers over others in different situations.
Head Geek
You'll be able to correct little annoyances I have with STL. For example, you can implement a size() method in O(1), instead of O(N)!
dicroce
+1  A: 

It looks like you updated the question so now there are really two questions:

  1. What should I do if I think the std:: library is too complex for my needs?

Design your own classes that internally use relevant std:: library features to do the "heavy lifting" for you. That way you have less to get wrong, and you still get to invent your own coding interface.

  1. What should I do if I want to learn how data structures work?

Design your own set of data structure classes from the ground up. Then try to figure out why the standard ones are better.

Daniel Earwicker
+3  A: 

You may be interested in EASTL, a rewrite of the STL Electronic Arts documented a while back. Their design decisions were mostly driven by the specific desires/needs in multiplatform videogame programming. The abstract in the linked article sums it up nicely.

leander
+3  A: 

A bit of my experience : Not that long ago I have implemented my own vector-like class because I needed good control on it.

As I needed genericity I made a templated array.

I also wanted to iterate through it not using operator[] but incrementing a pointer like a would do with C, so I don't compute the address of T[i] at each iteration... I added two methods one to return pointer to the allocated memory and another that returns a pointer to the end. To iterate through an array of integer I had to write something like this :

for(int * p = array.pData(); p != array.pEnd(); ++p){
  cout<<*p<<endl; 
}

Then when I start to use vectors of vectors I figure out that when it was possible a could allocate a big bloc of memory instead of calling new many times. At this time I add an allocator to the template class.

Only then I notice that I had wrote a perfectly useless clone of std::vector<>.

At least now I know why I use STL...

Ben
+1  A: 

As an example, using the STL spits out reams of incomprehensible and mangled compiler errors

The reason for this is essentially C++ templates. If you use templates (as STL does) you will get r*eams of incomprehensible* error messages. So if you implement your own template based collection classes you will not be in any better spot.

You could make non template based containers and store everything as void pointers or some base class e.g. But you would lose compile time type checks and C++ sucks as a dynamic language. It is not as safe to do this as it would be in e.g. Objective-C, Python or Java. One of the reasons being that C++ does not have a root class for all classes to all introspection on all objects and some basic error handling at runtime. Instead your app would likely crash and burn if you were wrong about the type and you would not be given any clues to what went wrong.

Adam Smith