Friday, June 8, 2012

Why I still hate, and yet grudgingly respect, C++

There are lots of great "Programmer to Programmer" questions on the sister-site to StackOverflow, called, where a lot of the general non-programming related questions that are somewhat software development related, but not exact technical questions with exact technical answers. Here's one I came across today:

  Why do so many people dislike C++?

The answers there are very good, but my favorite one is the answer that brings up a podcast conversation between Jeff Atwood and Joel Spolsky, two of the guys behind the whole "StackOverflow" empire, among other things.

 The gist of that answer is that you have to read a book about the "gotchas" in order to avoid writing really bad C++ code. A well-intentioned person who doesn't understand the difference between lvalue and rvalue references, copy constructor semantics, the intricacies of casting, const and non-const and when to use each, and the problems of writing exception safe code, concurrency and threading, and on and on...

 Well, I've always hated, but grudgingly respected C++, as a Delphi guy. I am in the C++ guy camp with the desire to have a binary that is standalone with no runtime at all, but yet, I see, that most of the Windows Visual C++ people seem to accept redistributing MS VC Runtime dlls along with their apps. Say it ain't so, m my C++ brothers.... DLLs that you ship should be your dlls only. Being forced to ship a DLL that contains some bits of your standard library is just so wrong on so many levels.

 Since the question on Programmers.SE covers enough of the reasons why you might hate C++ I'll just tell a story about why I hate C++. In 1995 I was working for a small software company making OS/2 software in C++. It was the last professional C++ job I ever held. I was using IBM VisualAge C++ for OS/2. In those days, writing code in C++ was rough. IBM actually had a nicer class library than most people, and their documentation was almost always right.  But it was shockingly difficult to write a database application in C++.

My main gripe was the lack of decent string handling libraries and capabilities in C++.
I counted at least four ways of writing string-processing code in our codebase:

 1. You could use IBM's non-standard-C++-library strings.   These had capabilities that the standard C++ library string types lacked, but the reverse was also true.

 2. You could use the standard-C++-library string types.   The most fun thing about using these was the absurd things that they did include, and the obvious things that they didn't include a way to do, requiring you to hand-code a tonne of string functionality yourself, over and over and over.

 3. You could use regular C char buffers and C pointer to char strings.  And you could then enjoy buffer overflows, and access violations, if you made mistakes.

 4. You could use your own class that basically used operator overloading, or whatever style you wanted to use, to try to provide the semantics that you wanted, as if you were programming in Visual Basic.  Most people started out using #1,#2,#3 and when they hurt themselves badly enough, they would start a side project writing their own C++ String Type. One String to Rule Them All.  Of course, they would then get lost in evil C++ side-effects involving casting, type coercion, lvalue and rvalue semantics, and so on. Oh, and string heap memory management.

 I saw all four of the above in use, and on three different occasions started writing my own C++ string classes, and it sickened me. I wanted one string to rule them all.  I wanted a string type built into the compiler that everyone would just use.

I had loved using Turbo Pascal in DOS, and in 1995 when Delphi came out, I saw that it had one, and only one string type. Sadly, it was the Pascal 255-character string type.  But when Delphi 2.0 came out, it was love at first sight. A proper String type built in.     Ironically, delphi now has a whole pile of string types, and the meaning of String has now changed three times (ShortString -> AnsiString ->UnicodeString)  and yet, we've survived it.

Back to C++ for a moment. You see, the codebases we used were so full of different string classes that I spent a lot of time converting string data from a standard library string to a character buffer or pointer to characters (PChar in delphi terminology).  The UI layer used the IBM string class.  The stored procedure layer used Char buffers and Char pointers with dynamic memory allocation (malloc).  In between, chaos reigned.

Now the above criticism isn't just about strings. It's that C++ is a giant playing field where millions of very talented developers have built giant monster piles of code. Half the world runs on the stuff they have built.

 And now I will switch from griping to respect mode.

 1. Microsoft Office is built in C++.

2. Almost every major Game studio writes in 100% C++.

3. No other language can do everything C++ can do, and yet compile to native code. Never has this been more true than since the advent of the new C++ 2011 standard. Check it out it's pretty neat.

 4. Finally, because of the tools, libraries and the rest of the C++ ecosystem, C++ is the most powerful cross-platform binary compiled language on the planet.

While I'm glad that I don't have to learn all the intricacies and accidental-complexity of C++, I do want to be able to link in C++ code into my Delphi apps sometimes, and for that reason, I'm quite excited at Embarcadero's future directions with LLVM/CLANG and C++Builder. In the microsoft camp, I'm truly impressed with their C++ 11 support in Visual Studio 2012. In the library and tools world, I'm deeply impressed by wxWidgets, BOOST, and the entire commercial ecosystem of C++ game development tools. Almost every major-studio game produced these days is 100% built in C++. So, let's give C++ a round of applause. And be glad if you've got a job doing Delphi and you don't need to understand copy constructors and type coercion, or discussing  some obscure massively-multiple-inheritance scenario you've devised.

1 comment: