FOREWORD

“C++ is a complicated language.” This is a reputation C++ has earned across a number of decades of use, and not always for the right reasons. Often, this is used as a reason to disallow people from learning C++, or as a reason why a different programming language would be better. These arguments are hard to substantiate because the basic premise they rely on is wrong: C++ is not a complicated language. The biggest problem C++ has is its reputation, and the second biggest problem is the lack of high-quality educational materials for learning it.

The language itself has evolved over the past four decades from C. It started off as being a fork of C (with minor additions) and a pre-compiler called Cfront, which compiles early C++ code to C that is then to be processed with the C compiler. Hence the name Cfront—in front of C. After a few years of progress and development, this proved to limit the language too much and work was undertaken to create an actual compiler. This compiler, written by Bjarne Stroustrup (the original inventor of the language), could compile a C++ program stand-alone. Other companies were also interested in continuing from basic C support and made their own C++ compilers, mostly compatible with either Cfront or the newer compiler.

This proved to be untenable because the language was unportable and wildly incompatible between compilers. Not to mention the fact that keeping all decisions and direction within the hands of a single person is not the way to make a cross-company international standard—there are standard procedures for that, and organizations that manage them. C++ was thus moved to become an ISO standard belonging to the International Standards Organization. After a number of years of development, the first official C++ standard came out in 1998, and people rejoiced.

They rejoiced for only a short while though, because while C++98 was a good definition, it had included a few new developments that people didn’t see coming, and had some features that interacted in weird ways. In some cases the features themselves were well-written, but the interaction between common features was just not present—for example, being able to have a filename as a std::string and then opening a file with that.

Another late addition was support of templates, which was the main underlying technology supporting the Standard Template Library, one of the most important pieces in C++ today. Only after its release did people discover that it itself is Turing complete, and that many advanced constructs could be done by doing computations at compile time. This greatly enhanced the ability for library writers to write generic code that would be able to handle arbitrarily complex deductions, which was unlike anything other languages in existence at the time could do.

A final complication was that while C++98 was good, many compilers were not suited for implementing templates. The two major compilers of the time, GNU GCC 2.7 and Microsoft Visual C++ 6.0, were both unable to do a two-step name lookup required by templates. The only way to fully get this right was to do a full compiler rewrite. . .

GNU tried to keep adding onto its existing code base, but finally went for a rewrite around the 2.95 time frame. This meant that there were no new features or releases for a multi-year period, and many were unhappy with this. Some companies took the code base and tried to continue its development, creating 2.95.2, 2.95.3 and 2.96—all three of which are remembered for their lack of stability. Finally, the completed rewrite GCC 3.0 came out. It was not very successful initially, because while it would compile templates and C++ code much better than 2.95 ever did, it would not compile the Linux kernel to a working binary. The Linux community plainly objected to modifying their code to adapt to the new compiler, insisting that the compiler was broken. Eventually, around the 3.2 timeframe, the Linux community came around and the Linux world recentered around GCC 3.2 and up.

Microsoft tried to avoid rewriting their compiler for as long as they could. They added cornercase upon cornercase and heuristic methods to guess whether something should have been resolved in the first or second template name lookup pass. This worked nearly completely, but libraries written in the early 2010s showed that there was no possible way to make all of them work—not even with source modifications. Microsoft finally rewrote their parser and released the updated version in 2018—but many people did not enable the new parser. In 2019 the new parser was finally included by default on new projects.

But before 2019, there was a major event in 2011: the release of C++11. After C++98 was released, major new features were proposed and worked on. But due to one feature in particular not working out quite as was expected, the new C++ release was postponed from around 2006 until around 2009. During that time attempts were made to make it work with the new feature. In 2009 it was finally removed and the rest was fixed up for release, and the 1998 version of C++ was finally updated. There were a ton of new features and library enhancements. Compilers were again slow to catch up, and most of the compilers could compile most of C++11 only by the end of 2013.

The C++ committee had learned from their earlier failure, and now had a battle plan of creating a new release every three years. The plan was to conjure and test new features in one year, integrate them well in the next, and stabilize and officially release in the third, and repeat this process every three years. C++11 was the first instance, and 2014 was the year for the second. Much to their credit, the committee did exactly as they had promised, making a major update over C++11 and enabling the C++11 features to be much more usable than they had been. In most of the places where careful limits had been implemented, the limits were moved to what was then considered acceptable—in particular around constexpr.

Compiler writers who were still trying to get all the C++11 features running well now realized that they needed to adjust their pace or be left behind. By 2015 all compilers supported just about all of C++14—a remarkable feat, given what happened to C++98 and C++11 before. This also renewed participation in the C++ committee from all major compiler writers—if you know about a feature before it’s released, you can be the leading compiler supporting it. And if you find that a certain feature does not match your compiler’s design, you can influence the C++ committee to adjust it in a way that makes it much easier for you to support, allowing people to use it sooner.

C++ is now experiencing a rebirth. This period started around 2011 when C++11 was introduced and the “Modern C++” programming style that it enabled was adopted. It has improved only so far though, because all the ideas from C++11 were fine-tuned in C++14 and C++17, and all compilers now fully support all of the features that you would expect. Even better, the new standard for C++20 will soon be released, and all compilers in their most up-to-date versions already support major parts of it.

Modern C++ allows developers to skip most of the original trouble of trying to first learn C, then C++98, then C++11 and then unlearning all the parts of C and C++98 that had been fixed. Most courses used to start with an introduction about the history of C++ because it was necessary to understand why some things were as weird as they were. For this book though, I’m including this information in the foreword because Josh rightfully left it out.

You don’t need to know this history anymore to learn C++. Modern C++ style allows you to skip it entirely and write well-designed programs knowing just the basic tenets of C++. There is no better time to start learning C++ than now.

But now to return to an earlier point—the lack of high-quality educational opportunities and materials for learning C++. High-quality C++ education is now being provided within the C++ committee itself—there’s a study group dedicated just to teaching C++!—and the latter issue is in my opinion completely resolved by the very book you’re holding.

Unlike all other C++ books I’ve read, this book teaches you the basics and the principles. It teaches you how to reason, and then lets you reason through the things that the Standard Template Library offers you. The payoff may take a bit longer, but you will be so much more satisfied to see your first results compile and run when you fully understand how C++ works. This book even includes topics that most C++ books shy away from: setting up your environment and testing your code before running the full program.

Enjoy reading this book and trying out all its exercises, and good luck on your C++ journey!

Peter Bindels

Principal Software Engineer, TomTom

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset