Late-Night Ruminations on C++
Way Back When
I think it was in 199X when I got my first experience of ‘serious’ programming. One day, being fed up with toying about with Delphi (it was relevant at that time, unlike now), I went out and bought one of those book+CD packages. The package included two books on Programming Windows with Visual Studio 97, a refernce book (essentially, a very large reprint of a chunk of MSDN), and the CDs containing a trial version (the equivalent of today’s Express) of Visual Studio. I installed it on my 166MHz 16Mb RAM machine, and I was hooked.
The fact that I got to actually write MFC apps was amazing. After all, MFC with all its insane macros and types such as CString that supplanted ordinary STL types (was there an STL back then?) were about as appropriate for learning C++ as it is appropriate to lose virginity with a horse. (Sorry, really crude example, but true.)
At any rate, I seem to have somehow survived MFC (without writing one single meaningful app, of course) and moved on to just writing console apps. At the moment I was trying to implement the gaming rules of AD&D (2nd edition, I beleive), and I distincly remember my excitement of learning about Microsoft’s __declspec(property) which, for those of you who do not know, allows one to have C#-style properties. Yes, we really had this capability ages ago (and still do).
However, at some point, C++ gave way first to Java, then to C#. I suppose that the real problem was the creating a good GUI app was much easier using .NET. That and the fact that C# had usable strings, memory management, and a whole host of other things. You dodn’t have to deal with arcane things such as Boost, and even STL which is arcane, especially if you consider its error messages.
Recently
Fast-forward a few years, and I’ve started using C++ again. Why? Well, I think the reason I got back into it was image processing. In C#, manipulating an image is easy (the API is very intuitive and System.Drawing.Bitmap is nice), but the speed basically kills the effort outright. So what I did is I started using P/Invoke to basically Lock() all the bytes in place, send it off to a C++ DLL to process, and then return the results back in.
Performance increased tenfold. And sure, you can fiddle around in C# with unsafe and pointers, but why bother?
Anyways, the real issue with C++ compared to C# to me, at least, seemed to be the fact that C++ is generally superior for parallelization. That’s why, at some point, I completely gave up on using the Microsoft compiler (which, to be fair, has improved in recent years) and focussed on using Intel Parallel Studio. The great thing about IPS is that, first, it’s a terrific set of compiler+libraries+tools, and is a real joy to use provided you invest some time in learning how it all works; and second, the Intel compiler is available on non-Windows OSs, which helps in terms of uniformity, even if I don’t use other OSs as much.
In terms of parallelization, .NET has TPL whereas C++ has
-
PPL
-
OpenMP
-
Intel Threading Building Blocks (similar to PPL, by the way)
-
MPI
Okay so maybe it’s not fair to bring all of these into the same category, but they all serve one purpose – speeding up code. And they do it pretty well. I’ve used OpenMP on a project, and this is basically ‘blind parallelization’, kind of like trusting TPL’s Parallel.For() to optimize your loop for multicore.
‘Modern’ C++
Today’s C++ is every bit as painful as the C++ of old. You still have to do the same menial things. In terms of what can seriously annoy a C#/Java developer, I can think of the following:
-
Having to manage your own memory. Worse yet, there’s lots of ambiguous ways of using all those funny
shared_ptr,unique_ptretc. containers, and it’s nearly impossible to figure out even for experienced devs, let alone the uninitiated. -
The lack of proper string literals as well as C++‘s inability to just bite the bullet and create just a compiler flag for how to treat strings has led us to the insanity of
char/wchar_t, various BSTR implementations, as well as the fact that I need to put the letter L in front of string literals. -
Truly insane compiler messages that Clang is supposed to be able to fix (err… I’ll beleive it when I see it).
-
Really messed up mechanisms for declaring/initializing arrays, as well as the equally insane idea that an array is just a pointer to the first element. And don’t get me started on multi-dimensional arrays.
-
The separation between header and implementation files results in huge amounts of wasted efforts. Personally, I try to avoid it by keeping everything in one single, huge .cpp file, but that’s not a good idea either.
On the other hand, there are reasons to use C++ nowadays. I’ve mentioned parallelization briefly, but there’s also C++ AMP, which is a way to transparently (ugh, more or less) execute C++ on a GPU. And of course, like it or not, interfacing with CUDA is a lot easier from C++ than .NET, though products are showing up all over the place that actually illustrate that it’s possible to just transcompiler. Still, if you go looking for jobs in the GPGPU space, you’re essentially looking at CUDA C which is, you guessed it, a C variant, so something closely related to C++.
Another advantage to C/C++ is that it’s a lot easier to integrate with .NET. I won’t talk about MC++ here, because this is a really ambigous product, but rather about P/Invoke – a technology that lets you transparently call C++ DLL functions right from C# (or indeed F#/VB.NET). Of course, you cannot use OOP structures from C#, but chances are you’re just optimizing a particular algorithm and you don’t need to import any hierarchies.
On the subject, there has been a few attempts to bring even OOP libraries to .NET. A good example is QuantLib which is a C++ library for quant finance (a topic very close to my heart). This library actually uses Boost for lifetime management, and of course it does use objects. Still, there are mechanisms which let you use it from .NET, though you must realize that you’re essentially getting a second-rate product.
Conclusion
There is no conclusion, since these are just my ruminations on a language that has largely gone out of relevance and now remains the niche of a few specialists. That’s not to say that it’s fundamentally bad, rather that it’s no longer something that warrants serious investment. In fact, I’d argue that knowing CUDA C is a more valuable skill than knowing C++, unless of course you’re job seeking in the quant space, where it’s still considered fresh.