Recs.
Updated
SpecsUpdate
Pros
Pro Powerful generic (meta) programming capabilities with templates
When you leverage the power of the c++ templating system enough, you can make the compiler execute a Turing complete program. You can even e.g. calculate prime numbers during compile time.
This is far more powerful than simple generics in e.g. Java and C#. On top of type safe containers one can use it to e.g.
- Static polymorphism (polymorphism without performance cost)
- More type safety without performance cost
- Functional programming / lazy evaluation
Pro Class destructor support
Resource Acquisition Is Initialization is actually a term used in c++ to basically say it has destructors. Originally it is used to free class resources.
But because class destructors are called guaranteed at the end of the scope of where a value is used, one can leverage this property to do all kinds of useful things which are not so nicely done in other languages. E.g. automatically close a file when it is not needed, close a socket, stop monitors, free resource handles etc. One does not need to remember to end a try-catch block with a finalize section, or call Dispose() on IDisposable class datamembers.
Pro Excellent compiler optimization
Both open source compilers (such as Clang and GCC), and proprietary ones (like Intel's and Microsoft's) are very good at analyzing program flow and program optimization. This is mostly due to the widespread usage of C/C++ applications running everything from mobile/desktop/server Operating Systems, to search engines and webserver software, and the demand for performance.
Pro Teaches problem solving
The great STL is the most powerful Data Structure and Algorithms Library. It would benefit you very much in problem solving, your main main way to love programming. The code is much compact compared to Java and C#. No unnecessary classes are in your way; yet when you need classes they are available unlike C. The code runs very fast.
Cons
Con No cross-platform dependency management
C++ doesn't come with a platform independent dependency management system like Maven for Java, Nuget for .net or Cargo for Rust.
Most solutions are platform specific, like Nuget for Visual Studio. In Linux the package management system is often used for c/c++ dependency management. (apt-get build-dep ...)
Con No two programmers can agree on which 10% subset of C++ to use
C++ is such a huge and complicated language, that programmers have to learn a disciplined subset of it to reliably get anything done. The problem is, no-one can agree on which subset to use and they can't understand each other.
Con Undefined behavior
Subtle errors can render the entire program "undefined" by the complicated C++ standard. The standard imposes no requirements in such cases. Thus C++ compiler writers are free to ignore the existence of such cases and Bad Things are prone to happen instead. Even experts can't reliably avoid undefined cases in C++, so how can beginners be expected to do so?
Con Separate header files
One has to duplicate e.g. object interface declaration in header files.
Making some object member public is not enough to make it accessible for other cpp files.
However the feature request for module support is high on the wishlist. This would solve this issue.
Con Module system is not great
C++ uses the #include
mechanism provided by C. Which unfortunately is a poor way of accessing the API of a library. Some of the reasons why the module system is weak are:
Compile time scalability: The compiler must preprocess every header included in a file, and every header included in those headers. This process must be repeated for every translation unit in the program. As can be imagined, this doesn't scale very well. For each header added you are increasing the compilation time exponentially.
Fragile: modules included are treated as textual imports by the compiler. This causes all sorts of problems since they are subject to any macro definitions in the time of the inclusion. If any of these macro definitions collide with a name in the library it can break the library API .
Con A chaotic mingling of programming concepts
To give a similar picture: C++ does have more of a motor combustor, that is responsible to vaporize the gasoline. A bad principle corrected many times. At the end we have a complicated machinery that is a weird collection of a few genius ideas to make the whole thing work (templates (weird and a lot of history-driven pitfalls), now: lambdas (in a weird way), still a lot of exceptions in how compilers machinely set up the classes). Weird new rvalue mechanisms. Too much backward compatibility where all the old and erroneous stuff still exists, and the smart pointers emerge, and et cetera. Everything is just mingled together. And when you want to templatize your existing code, you have to start over from the beginning.
Like Scott Myers said it: "C++ is a foundation of programming languages". Yes, a weird one. Result: your coding solutions do not scale. You do not know, where you end up in refactoring.
Con N different ways to do things -- most deprecated
C++ has retained every ancient feature in the name of compatibility. (Consider dynamic memory: malloc, then new, then smart_ptr, then unique_ptr and shared_ptr.) Which is great for old codebases, but now you're using libraries from every period that do things differently and lots of boilerplate are necessary to unify all of these.
Con After all these years of trying, still no decent string library
Although you have several ways to handle strings, all of them are messy and error-prone, giving birth to many crashes and memory corruptions in the field. It's one of the worst languages ever, if you have to do strings.
Con Undefined behaviors and weak limited type safety
Undefined behavior in a program can cause unexpected results, making it hard to debug. With UB, program behavior may vary wildly depending on optimization settings. There are many cases that invoke UB, such as signed overflow, invalid dereferences, large integer shifts, uninitialized variables, etc. C++ allows for non-type safe operations such as logic errors, wild pointers, buffer overflow, etc. UB and type safety issues create a large number of bugs and security vulnerabilities.
Con C++ succumbs under its own weight
The years of cramped backward compatibility start to show in the syntax, complexity and very top-heavy language structures. Trying to keep up with far more elegant languages like C# doesn't do C++ any good either, because the committee always seems to be able to mess it up. After numerous years, still no modules... you must be kidding!
Con Memory leaks and segmentation faults
Because C and C++ allow the user direct access to memory and don't provide garbage collection threads, there is a probability that a program may have a "memory leak", which occurs when something a programmer allocated in the heap is not deallocated properly. Also, attempting to dereference memory protected by the operating system causes a segmentation fault and kills the program.