Has C++ jumped the shark?
johndcook.com
johndcook.com
Unsolved things:
- Unified C++ ABI call for making shared libraries without worrying about compiler manufacturer or version.
- Massive bloat. Take a look to the Boost libraries and cry.
- Poor debugging tools for templates (debugging templates it is crazy, and the promise of easy template debugging is almost a decade old).
Ridiculous things (in my opinion):
- Obsession for doing everything in "user-land" (e.g. source code templates) instead of built-in abstractions at object code-generation time instead of compile-time.
- Willing to introduce functional programing in the language, when, in my opinion, it makes more sense just to interface with true functional code (e.g. via SBCL).
C++ hour will come, with a non-bloated, system-software capable, "better than C", which could be labeled "simple C++", as in "simple English".
Indeed!
The thing I don't understand is that you go to the boost library website and you see that it touts itself as an all-volunteer effort.
Who are these people who volunteer their time to produce this massively bloated, over-elaborated code? What is their motivation? What's going on here? I understand bureaucracies usually bureaucrats are paid and produce code and memos to expand and control their turf. But here? What's up?
Boost certainly seems well done for what it is. But does this particular niche attract so many people?
There are many different components in there.
If you can give me an example of a part of this "continent" which is "lean and mean" rather than over-elaborated, I'd be grateful.
Also, as far as I know, most compilers were settling on a fairly standardized IA64 ABI, even for other platforms. The problem gcc had, last I checked, was after every release, they found a bug in the implementation and fixing it made the next release incompatible, but the goal was to be interoperable.
There's too many implementation decisions for this to be feasible. E.g., you'd have to standardize exception handling implementations and object layouts.
In practice, GCC has tried to standardize a C++ ABI for some platforms, but each proposed "standard ABI" has been buggy and required at least moderately backward-incompatible ABI changes between GCC releases.
> Massive bloat. Take a look to the Boost libraries and cry.
Define "bloat"? Large parts of Boost are absolutely horrid (e.g. Spirit), but I don't know what you mean by "bloat". Do you mean that the resulting object code is big?
> Poor debugging tools for templates (debugging templates it is crazy, and the promise of easy template debugging is almost a decade old).
Agreed. Hopefully clang is fixing that. http://clang.llvm.org
> Obsession for doing everything in "user-land" (e.g. source code templates) instead of built-in abstractions at object code-generation time instead of compile-time.
Huh? What do you mean by "built-in abstractions at object code-generation time"?
> C++ hour will come, with a non-bloated, system-software capable, "better than C", which could be labeled "simple C++", as in "simple English".
I was hoping that Digital Mars D would be the "Simple C++", but it feels like D is losing momentum.
(Sidenote: I've been programming in C++ for about 13 years, and am a recovering C++ "language lawyer".)
I was hoping for the same for a long time. Now my favourite "simple C++" is OOC (http://ooc-lang.org/). The syntax is a bit different (partially justified by faster parsing/compilation and has a lot of nice sugar), but it does support a lot of the good stuff: classes, generics, ability to use C-layout structures and attach "methods" to them, closures, pointers to allow easy C libs interaction and more...
Aside from your tears, what is the evidence that boost is bloated? Too slow? Too much source code? Too many files?
I've been using Boost for nearly a decade. It does a ton of useful stuff (from template metaprogramming to fast matrix algebra), it's loosely coupled, and it's insanely fast. Given it's scope, it's the least bloated library of which I know.
C++ has been evolving, but for the last decade, all of the evolutionary changes have come in the world of templates and template metaprogramming. I think this is hard on the people who have restricted themselves to the C-with-classes mentality. They're missing every modern development in the language since ~1998.
With gcc 4.4.5 and -O2, this one small file takes 22 seconds (!) to compile and produces a 14MB output file.
I guess that's... tolerable. But it isn't "lean" in any meaningful sense.
Your point seems to just be agreement with mine: C++ bloat is tolerable. It's still bloat.
Seriously, I think it's too much trick to do meta-programming in the language. If meta-programming should be allowed, it should be easier, simpler, and for the ordinary people. Just like Ruby.
But why does the metaprogramming syntax in C have to be so convoluted, bloated and difficult? Do we really need >30 second compile times per file on recent CPUs? If a language is hard to parse both for computers and humans, something went wrong. It should be easy to read for one of both, preferably both.
It's actually not all that fast in a lot of cases. Boost's matrix manipulation support is particularly slow:
http://eigen.tuxfamily.org/index.php?title=Benchmark-August2...
Also a lot of the template aerobatics generate a ginormous number of symbols which massively increase the binary size and cache pressure. In a former life I ripped out a pile of heavily templated code using Boost and replaced it with a well placed virtual function or three and dramatically reduced the cache misses in the application.
I've always seen Boost (and to a large extent the STL) as a demo library to show off what's possible with templates rather than something to be used in everyday code and have worked on a number of projects which forbade both.
There's a large rift in the C++ world between what I generally label Qt and Boost camps. The Boost people see the Qt folks as Java-esque dimwits that can't be bothered to learn the full extent of C++'s power and the Qt folks see the Boost following as unpragmatic architecture astronauts.
You've picked a benchmark of the most highly optimized matrix algebra libraries, and found that uBLAS is mid-pack, even though a) it isn't particularly optimized for any platform, and b) its goal is to result in the clearest possible syntax without sacrificing adequate performance. Talk about picking nits.
"Also a lot of the template aerobatics generate a ginormous number of symbols which massively increase the binary size and cache pressure."
When it really matters (which it rarely ever does): man strip
"I've always seen Boost (and to a large extent the STL) as a demo library to show off what's possible with templates rather than something to be used in everyday code"
I worked on shipping commercial products that used boost and the STL, and I did nearly all of my speed-sensitive code with it in grad school. It's far more than a demo library. Like I said before, you don't have to use all of it to use some of it.
Second of all, those symbols will have an effect on compile times, but they should certainly be stripped out by the linker. Why would symbols that do nothing sit in the executable?
Thirdly, Boost's purpose is to iterate faster than the C++ standard library and have real-world data about what libraries work and are needed. Those libraries would then be included in next C++ standards, as it has happened with TR1. There are useful libraries inside Boost and there are research libraries or concept libraries. Don't use a library just because it's included in Boost!
I use Boost and Qt. Since TR1 I didn't need Boost as much, which means that it's achieved one of its goals.
This I think is the power of C++ - it is a multi-paradigm language, and you are perfectly free to not use some of the paradigms, or more powerful techniques.
I would like to see something better come along that has some of the low-level power of C, but also supports sophisticated high-level abstractions. I was hoping Go might fit that bill, but the Go designers have made some interesting choices that seem to alienate a lot of developers.
I was trying to say that he (is that you??) understand more about C++ than almost everybody.
Objective C this very well. It adds classes and protocols. Closures can be implemented with blocks. Everything else is the same as in C.
However, much of joy of using Objective-C is Apple's Cocoa Foundation classes. Stuff like autorelease and NSString are not part of Objective-C's core language. And support for Objective-C or Cocoa on non-Apple platforms is limited or not well-supported.
As you've said: everything else is the same as in C.
(Edit: Small change to make meaning clearer)
Note also the ability to extern templates added in C++0x, which allow you to collapse common instantiations to a single object file.
One example of templates affecting runtime performance is poor use of the instruction cache due to code duplication in every instantiation of a template.
What is the point of controlling all of those things? The GP was talking about speed - how are GC, JIT and images related to this?
Precise GC is asymptotically more efficient than manual allocation; you need to use other approaches, like arenas, to get back that lost time, but they are not always applicable or easy to introduce.
Optimizing virtual method calls at runtime (e.g. monomorphic or polymorphic inline caches) is rather awkward without JIT. Similarly, C++ templates cannot be instantiated at runtime, meaning less efficient, more general and indirected code needs to be used instead.
Images optimize startup hugely: they completely remove the need for any initialization not directly related to acquiring external resources. For example, this is one of the biggest reasons Chrome is so quick to start up - it uses freeze-dried heaps in V8 (its Javascript engine).
1. GC is fast at the cost of using more memory, which it turn slows the entire app down. 2. JIT can do all those optimizations, but how many of them are done in practice? How fast is the software compared to a binary compiled in C or C++? 3. Can be useful, but the only software that I've seen having trouble with startup times in the first place is written in .NET and Java :)
I guess that what I'm getting at is that C++ code is still faster than e.g .NET code even if C# has GC and JIT. In the end that's all that matter, not whether you can do optimization X.
I'll assert that memory is not normally a constraint in most situations that need to scale (i.e. not constrained clients), these days. (Though I will say I have noticed that Firefox 4 is significantly slower than FF 3 when switching tabs, and I believe it's because of memory reduction optimizations they've put in because of everybody moaning about bloat. I'd prefer it use more memory and less CPU.)
JIT optimizations like PICs? For over 20 years. The benefits are magnified in languages that make many operations virtual, so you see it in things like Smalltalk (very long time), Javascript (Chrome's V8) and Java JVMs (methods virtual by default so it's a win).
Re slow startup - you're deluding yourself if you think there isn't much software that doesn't have startup time issues. I need only restart any machine I have to know how slow initialization is; with HDD transfer rates in excess of 100MB/sec, there's no good reason for it to take more than 10 seconds or so when no hardware has changed. You're simply not aware of how much faster things could be if startup were faster because you're used to how slow everything is. You just know you can't e.g. fork utility X more than 200 times a second in a script, but don't realize it might be 10 or 100 times faster with a different approach.
We need system level languages and C++ currently stands alone in its combination of powerful abstractions, low level control, and ecosystem size, though it certainly has competition in these aspects individually.
I don't doubt that a language could be everything C++ is and much cleaner too, but that is a big challenge that relatively few language designers want to take on.
There's some "good stuff" in C++1x, but of necessity, it's all additive, not subtractive. So the language gets bigger and more complicated.
I've never met an adept C++ programmer who didn't aggressively cut the language down to a subset. The sad thing is that I've met good C++ programmers - and seen good C++ libraries and frameworks - whose subsets are quite distinct; they are 'divided by a common language', like the old cliche goes.
This is a little inconsistent. As a language that takes a long time to master, changing fundamental features of the language every 3rd year, for instance, would be a bit difficult to keep up with. Furthermore, the niche C++ lives in isn't one that needs to change every year. For some users, language stability and backwards compatibility are key, and with things like Boost, additions to C++ can be tried out in the wild for many years before being standardized (as many features slated for the newest standard were).
As always when talking about the continued relevance of C++, I will celebrate when I'm proved wrong.
As I see it, the new standard just isn't something which would change the future of C++ in some significant way, and it is not the most pressing problem C++ has as a language.
From my perspective, what I would like to see more is some alternative to boost, with similar functionality but without that meta-meta-programming. ;-) Simply, more cross-platform libraries comprehensible for the average C++ programmers.
Focus on your skill not the tools. Surfing is more about timing, fitness and knowledge of waves than it is about the board. Likewise coding is more about RAM, CPUs, HDs, GPUs, busses, networks and ultimately users than it is about what tools you use to manipulate them.
My coding is primarily about managing complexity through good abstractions, and sometimes doing optimizations. Different languages are better suited to good abstractions. Kelly Slater might use a coffee table for fun one time, but he won't use one for his next competition.
It's like saying "famous author X used pen and paper, hence complaining that Word 2010 doesn't handle Y properly is silly - focus on your writing!" (Worse even, as for pure writing, the speedup between pen/typewriter/Word is probably less pronounced than between programming languages.)
I saw a table tennis player all excited about his new carbon fiber paddle. Then one of the club champs picked up the box the new paddle had come in and, using the box as a paddle, proceeded to defeat the player with the carbon paddle.
It was absolutely hilarious how pissed this guy was getting with his fancy paddle and his attempts at tricking my professor with trick shots.
It means that part of being an expert craftsman is having the experience and skills to select excellent tools, and the experience and skills to drive those excellent tools to produce excellent results. Blaming your tools means either that you lack skill, or that you chose your tools poorly because you lack the experience and skills to choose correctly. Sitting there and defending bad tools does not impress me; it makes you sound like a craftsman who can not tell the difference between good tools and bad tools... and that's a bad craftsman.
Yes. Tools matter. Good tools won't bring you to your optimum peak performance on your own, but bad tools will guarantee you'll never get there. Bad tools typically take longer to work with, and typically teach bad habits to get around their deficiencies.
Da Vinci with a mop and a bucket of mud may be a better painter than you, but he would never beat Da Vinci with quality tools.
Maybe. But Da Vinci would never paint the Mona Lisa with a mop and a bucket of mud. If he did, it wouldn't have survived to modern times. Am I stretching the analogy too much?
Paint Mona Lisas, people. With amazing skill and great tools.
think about that a minute.