Attention: are you here because you want to learn C++?
I love C++.
C++ taught me how to really write code.
Back in the day I would study the intricacies of the language, Standard Template Library, and all the nuances of memory management and pointer arithmetic. Those were some seriously good times. I remember reading Scott Meyers Effective C++ book series over and over again. Each time I would learn something new or grasp more of how to use C++. I’m saying all this just to let you know that I don’t hate C++. I love C++. There are plenty of excellent developers I know today that still use C++ and teach others how to use it and there is nothing at all wrong with that. So what is the problem then?
The new message is wrong
C++11 just came out recently and it seems like there is this big resurgence in interest in C++ development. Now don’t get me wrong. C++11 is fantastic! I am in just about 100% agreement with all of the changes that have been made. C++ has definitely become much easier to use and it has even become more powerful. There is one thing it didn’t become though—and this is the most important—more simple. It seems that many of the seasoned developers have forgotten why we stopped using C++ and moved on to Java, C# and other modern languages. Many younger or newer developers don’t really know the history and are getting confused by the current C++ message and resurgence. Everyone keeps asking me if they need to learn C++, but just like my answer was a few years ago, it is the same today—NO! Ok, so “NO” in caps is a bit harsh. A better answer is “why?”
Why do you want to learn C++?
There are only about three sensible reasons to learn C++ today that I can think of.
- You absolutely need to eke out every bit of performance possible out of your software and you would like to do that with a language that will support OO abstractions.
- You are writing code which will directly interface with raw hardware. (Example: you are writing a low level driver.)
- Memory control and timing is of absolute importance, so you must have completely deterministic behavior in your system and the ability to manually manage memory. (Think real time embedded operating system controlling a moving piece of machinery.)
Now it is possible I missed a valid case, but chances are any other case is going to roughly fall into one of these three categories. Wait! Wait! What about portability? No! Please don’t learn C++ thinking that you will build software to work anywhere. There are plenty of other options today for doing that and C++ is not nearly as portable as many people believe or tout. The lower level the abstraction is the more different each operating system and platform is. Also please don’t tell me C++ gives you more power and control to do exactly what you need. Most software development is about managing complexity not about being able to twiddle bits at a lower level. In almost all cases of modern large scale software development, higher abstractions, not lower abstractions, are what you want.
But, I want to learn C++ anyway
Ok look, I know you think Windows 8 is cool and all the cool kids are learning C++ to write their Windows 8 applications, but you should know what is in the Kool-aid before you drink it. Writing C++ code is not a picnic. Even with all the changes in C++11, C++ is still a very difficult language to learn and an even more difficult one to master. You’ve probably heard this common quote about C++:
C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do, you blow away your whole leg! — Bjarne Stroustrup
And if you don’t know who Bjarne is, well, he invented C++. So if he says that about the language, I am sure you can draw your own conclusions. I keep hearing that C++11 makes things so much easier now and that C++11 has fixed many of the problems of C++98. I don’t doubt that it has. What it hasn’t fixed is the size and scope of the language—it has actually increased it. Sure, you can use a subset of C++. Sure, you can use smart pointers in the new C++ to prevent you from having to manually manage memory. You can utilize lambda expressions to declare functions in-line instead of passing function pointers. Automatic type deduction is a much needed breath of fresh air. The problem is you still have to know the old way of doing everything and you have to understand exactly what is really going on when you are debugging a C++ program which is easily capable of stomping memory (something you probably have never even heard of if you were born in a managed code world.) You will encounter C++ code from 20 years ago and it will look like a different language entirely. Here is a list of actual interview questions that I used to ask C++ developers interviewing for a job I was hiring for.
- How many ways are there to initialize a primitive data type in C++ and what are they?
- Why should you declare a destructor as virtual?
- What does it mean that C++ supports overloading?
- What are examples of overloading in C++?
- What is name mangling in C++ and why is it used?
- What is an abstract base class?
- What is RTTI?
- How can you access a variable that is “hidden” by another variable of the same name?
- What is a namespace and how is it used.
- What are the differences between a class and a struct in C++, and how does this compare to C?
- What are templates? How are they used?
- What is a copy constructor and when is it used, especially in comparison to the equal operator.
- What is the difference between a “shallow” and a “deep” copy?
- What is the const operator and how is it used?
- What are the differences between passing by reference, passing by value, and passing by pointer in C++?
- When is it and when is it not a good idea to return a value by reference in C++?
- What is the difference between a variable created on the stack and one created on the heap?
- How do you free memory allocated dynamically for an array? What are the implications of just using delete?
- What is multiple inheritance? When should it be used?
- What is a pure virtual function?
- What does the keyword mutable do?
- What does the keyword volatile do?
- What is the STL?
- What is a Vector?
- What is contained in the <algorithms> header?
- What is the difference between #include <iostream.h> and #include <iostream>?
- What’s the difference between “++i” and “i++”?
- What is short circuit evaluation? How can it be used? Why can is be dangerous?
- What is the ‘,’ operator?
- What is the only ternary operator? How is it used?
- What is the use of a const member function and how can it be used?
- How is try/catch used in C++?
- Why should you never throw an exception in a destructor?
- What is the explicit keyword?
- What is the proper way to perform a cast in C++?
- What does inline do?
Some of these questions have the same answers for C# or Java, but you can see from this list that C++ is very, very deep. There is just a very large amount to know about the language itself. C# and Java development are somewhat about learning the language, but much more about learning the libraries. C++ development is more about learning every nook and cranny of the language.
C++ is the wrong direction for the future
The big problem is that programming languages really need to get simpler and increase the level of abstraction not reduce it. There will always be a need for low level code, but a majority of the code that we write today is at a much higher level. I first jumped off the C++ ship many years ago when I finally could no longer make the argument that I could develop apps faster in C++ than C#. I held out for a long time trying to believe that all the investment I had made in C++ was not lost, but it turned out that C# simplified things to such a great degree that the extra power C++ gave me was not worth the extra responsibility. Just as I was taking a break from writing this blog post, I happened to stumble across a newrevitalized project from Microsoft Research called touchdevelop. This is the direction we need to go. We need programming languages to be even simpler to use, not more complex. Now don’t get me wrong, you are pretty severely constrained in touchdevelop, but I believe something similar to this is the future. It seems that Microsoft is making a decent push for bringing C++ back to mainstream with C++ support in Window 8 and attempting to kill XNA, but I think there is a warped perception of the development community that seems to be entrenched in the minds of Windows OS developers about programmers wanting to use C++. I just don’t ever see myself moving back to a more difficult language when I can write C# on just about every platform now. C# is not the perfect language, but it is very elegant and simple.
Some parting words about C++
With all I said above, I still believe that there is some value in learning C++. No, I’m not trying to contradict myself here. Allow me to explain. If you can program in C++, you can program in any programming language. If you understand how stack and heap memory work, pointers and references and all the low level details that make C++ so tricky, it will help you when you are working at higher abstractions and in understanding how computers work in general. My point of this post is not to bash C++ or bash people using C++ or teaching C++, but rather to blunt the message that seems to be being preached by an over eager C++ community. Everyone is not going to become a C++ developer and they shouldn’t need to be. While C++ may have the ability to make your program more efficient (in certain scenarios,) it is extremely unlikely to make you more efficient at creating your program (except in some extreme cases.) So, I am glad C++ got a much needed overhaul, but I don’t think it is going to make a comeback any time soon, and that is a good thing.