- source control systems: it keeps source backed up, it allows for revertions, and stops people trampling on each others work. All good. But it also leads to a fair bit of hassle - exclusive check-outs often make you wait for a file, shared check-outs make you waste time merging and checking automated merges. It also holds up bug fixes because a one-liner fix may now have to go through the update/merge/commit cycle.
- exotic architectures: it's often quite cool to write extensive systems that make a certain complex idea possible. eg. Call a function, and have it executed on multiple servers and clients automatically, with all passed in data members correctly serialised and reconstructed. Grrrreat idea. Now try wrestling with the lengthy code needed to create such functions and the data, and the 48-page long template errors you get at the slightest typo.
- data backed by SQL databases: these give you automatic persistence, standardised querying facilities, easy ability to locate your data on a different computer to the program doing the querying, etc. All good. Now try to write a common interface for such SQL-enabled objects, get it to work across inheritance, and guarantee that the code stays in sync with the SQL statements required to create the database. I never knew adding two integers to a C++ class could take 3 weeks before, but now I do.
- using complex template libraries like Boost: as seen in recent threads on the forums, many people swear that Boost makes their life easier - and it does - but Boost also makes your compile times longer - which it does. Longer compile times can't be shrugged off as irrelevant, as the compiler is a valuable tool in checking your code correctness at the low level, freeing you to think of the high level tasks. Faster builds also facilitate running tests, whether of an informal nature or of the Test Driven Development variety. Using complex template types inevitably means inserting them into headers, and that means bigger build times, and probably a reluctance to refactor code due to this. People talk about using the pImpl idiom to help here, but let's not kid ourselves - the pImpl idiom is a workaround to sidestep problems with the language. It's extra work, no two ways about it.
All these facilities do Great Things. There's no denying it. But you pay a price. And I fear that all we're doing is shuffling the burden around rather than eliminating it.
I think the answer to some of these problem will look something like a word that starts with 'P' and ends with 'ython', but I'll go into that another time.