Around a month ago, Herb Sutter gave a talk on why C++ is once more gaining relevance in the world of programming, and how after a decade of neglect and abandonment, it is set to pave the way into the future. I downloaded it a while ago and finally had a chance to watch it last night; the talk itself is most-excellent and is around 40 minutes long, you can stream it online or download it in a higher-resolution format on Channel 9. Or click below to watch:
As someone that’s been using both C/C++ and .NET extensively over the past years, I found there was one very important point that Sutter glanced on, danced around, and did everything short of actually naming in his talk and it’s that if you’re doing anything remotely intricate or complicated, leaky abstractions in managed languages will bite you in the ass, and end up lowering your productivity, some times (and if what you’re working on is truly complicated, often times) to a point where you’d have been more productive using C or C++ in the first place.
The concept of leaky abstractions isn’t anything new and I’m hardly the first to point out how it can turn a knight in shining armor into a harbinger of doom and destruction. It’s the number one problem fundamentally present in almost any framework, but even more so in managed languages where the framework is all you have, and you’re not allowed to side-step it and build your own foundations to work with (p/invoke and interop aside). But lately it’s becoming more and more of a problem as the “push” for innovation that Sutter speaks of has become a fundamental requirement in just about all corners of the industry.
5 years ago, few in the .NET community could tell you what p/invoke was and how you’d use it. Now, it’s considered fairly basic knowledge and a working familiarity with the underlying C WIN32 API is a must for any desktop software developer looking to make a memorable, high-performing product in the world of .NET. Pretty much each and every WIN32 API documentation page on MSDN has a comment from someone on how to import that particular function into .NET with an interop definition, and people are running into the limitations of the managed framework far more often than they used to.
I’m still a big fan of .NET in general as it makes it really easy to quickly jump from idea to prototype to finished product for quick, one-off applications or basic tools and utilities. Even for huge products and projects, .NET’s GUI tools far exceed any C++ offerings in terms of ease-of-use and even functionality when it comes to having standard controls and features a single click away. But the leaky abstractions in .NET are proving to be a real pain in the back, and sometimes even interop just doesn’t cut it for the most trivial and basic of things.
Recently, I hit a wall with .NET in attempting to make EasyBCD support the parsing of internationalized BCD output in the form of bcdedit’s stdout. bcdedit, like many other Microsoft tools and utilities, is only UTF8 or Unicode aware if the console codepage is explicitly set in the application’s console window. I spent an entire day trying to shoehorn this functionality via various .NET hacks and failed interop attempts, a week off-and-on testing and debugging my various incomplete solutions, and in the end my solution was to create a C++ “proxy” application that would create a console, set the codepage to UTF8, run the command line utility, and pipe the output back to the host (source code here, MIT license: UtfRedirect). It was a guaranteed fix, took all of half an hour including testing it on 4 different platforms and experimenting with various internationalized stdout texts.
I personally believe the “best” compromise for medium-sized projects is to use C#/.NET to create the GUI and small helper scripts/utilities, but to build the core in C++ with an exposed C API or commandline interface. The short and long of the matter is, making a language truly and properly productive is a lot more work than just providing a sandbox with prettied-up API calls. You have to organically add improved productivity into a language from the bottom-up, making sure that the productivity goes hand-in-hand with power and flexibility, that it always second fiddle to being able to get the job done; after all, what use is a one-liner code if no mater how you twist and turn you can’t get it to do what you want?