[quote name='mhagain' timestamp='1300050170' post='4785347']
I've used both C and C++, but prefer to restrict myself to the C-like subset of C++ with maybe a few C++ specific features here and there. I don't subscribe to the thinking that "if you're not using STL/new and delete/etc you're not using C++" and I've seen enough C++ code that focusses more on designing pretty class structures than on actually getting the job done.
One reason I can think of to prefer C is that it compiles faster.
So what do you use for collections? How do you manage memory? If you're focused on "getting the job done", why not use a proven set of tested tools?
While C++ compile times are a pain, I would argue that they are less painful than the alternative. That said, I wouldn't use C or C++ if I had the choice.
[/quote]
If you find that your biggest time sink is memory management and collections, you have bigger problems. Besides, in my experience, STL has it's own issues.
1. Say you are trying to optimize some critical execution paths. You find some areas where an std::vector is created, populated, and passed around to a few methods for manipulation before handing it off to a library. For whatever reason, the vector would be more efficiently allocated on the stack, as certain characteristics are known. Great, you just need to write a custom allocator and you're all set, right? Not quite...unfortunately, the newly defined std::vector type that makes use of the custom allocator will no longer be compatible with the type required by the library call.
2. STL collections are not thread safe. Usually this is acceptable, as in the worst case scenario, collections can be made thread safe via some sort of synchronization. However, this may not be optimal. Consider a linked list. In the optimal case, the mutex only needs to be acquired for a very brief moment -- when assigning the next/prev/head pointers. The allocation and initialization of the node/type can be done outside of the lock. Using an std::list, this isn't possible. The mutex needs to be wrapped around the call to list.push_back (or whatever method you use), which means you are locking needlessly over the duration of the memory allocation and initialization of the type. In some cases, this is acceptable, in others, it's not.
3. The rules for iterators are a pain. For example, when are iterators invalidated for a linked list? What about a deque? What about a map? What about a vector? Yea, it's very difficult to keep track of, and have encountered way too many bugs as a result. Also, this makes it very tricky to just 'change' the container type.
4. Using the STL adds lots and lots of line noise to your source code. You either need to riddle your code with typedefs, or live with never-ending std::map<std::string, std::pair<std::vector<foo>, int> > lines. Yea, I hear C++0x introduces 'auto' to 'fix' that, but that's just a whole other can of worms. C++0x has its own problems. And still, 'auto' won't save you from the 20 line template compiler errors.
5. While not necessarily a flaw in the STL itself, I've found that using the STL encourages a 'lazy' atmosphere. I can't count the number of times I've seen code such as:
std::map<> m;
if(m.find(foo) != m.end())
use(m[foo]);
Or looping and doing collection.push_back() without reserving the length (again, sometimes acceptable, sometimes not.)
6. STL (or maybe this belongs more in the C++ critiques) has spawned an entire cult of syntax optimizers. With C++, very very subtle syntax style can negatively effect performance. Take this rather basic example:
for(std::vector<>::iterator it= v.begin(); it != v.end(); it++){} // Where's the performance problem?
C++ *is* a terrible language, and the STL doesn't save it. C++ requires loads and loads of context just to fully understand simple snippets of code. You need to examine methods, determine if those methods are being overloaded, make sure those '+' signs aren't overloaded, decide how member variables are shared between class hierarchies (multiple virtual inheritance anyone?), figure out if any exceptions might be thrown that yank you out of the code path you think is being executed, etc, etc.