Modern C++ - nuwen.net

Patterns and structure out of the formless void

Modern C++

"Learning the fundamentals of a programming language is one thing; learning how to design and implement effective programs in that language is something else entirely. This is especially true of C++, a language boasting an uncommon range of power and expressiveness. Properly used, C++ can be a joy to work with. An enormous variety of designs can be directly expressed and efficiently implemented. A judiciously chosen and carefully crafted set of classes, functions, and templates can make application programming easy, intuitive, efficient, and nearly error-free. It isn't unduly difficult to write effective C++ programs, if you know how to do it. Used without discipline, however, C++ can lead to code that is incomprehensible, unmaintainable, inextensible, inefficient, and just plain wrong" - Scott Meyers, Effective C++, Third Edition

"Mallow had swung the steel sheet onto the two supports with a careless heave. He had taken the instrument held out to him by Twer and was gripping the leather handle inside its leaden sheath. 'The instrument', he said, 'is dangerous, but so is a buzz saw. You just have to keep your fingers away.' And as he spoke, he drew the muzzle-slit swiftly down the length of the steel sheet, which quietly and instantly fell in two.... 'Just one more demonstration. Bring two short lengths of pipe, somebody.' ... Mallow stood them upright and shaved the ends off with a single stroke of the [nuclear] shear, and then joined the pipes, fresh cut to fresh cut. And there was a single pipe! The new ends, with even atomic irregularities missing, formed one piece upon joining" - Isaac Asimov, Foundation

Most people would say that C++ is one programming language among many. That's superficially correct, but it's fundamentally incorrect. Scott Meyers says in Effective C++, Third Edition Item 1 that C++ consists of four sublanguages: C, object-oriented C++, template C++, and the STL. That's a deeper insight, but I prefer to look at it in another way.

There are two forms of C++: archaic C++ and modern C++. They share the same lineage, which is long and fascinating. However, they are now deeply divergent; experienced practitioners of one form can barely understand code written in the other form. (This is somewhat more true in one direction than the other; modern C++ programmers can understand archaic C++ in the same manner that modern English speakers can understand Chaucer.)

C++ is a very old language. Its oldest ancestor after C, named C With Classes, dates back to 1979. It was named C++ in 1983 and AT&T started to use it internally that year. Basically, the language is as old as I am. In the 1990s, as people gained more experience and compilers improved, C++ started diverging into two forms. However, the language was not Standardized until 1998, and compilers reasonably conformant to the Standard did not appear until 2001 (GCC 3.0) and 2002 (Microsoft Visual C++ .NET 2002 (7.0)).

Programming modern C++ on an archaic compiler is like ice-skating uphill. People tried to do it, and some of them mostly succeeded, but it was really hard and nasty. Now we can try to forget that it was ever necessary. With the release of modern compilers, it became possible to use modern C++ easily. I therefore claim, somewhat arbitrarily, that modern C++ split from archaic C++ in 2001. (Coincidentally, this is when I began learning C++.)

So what is modern C++, and how does it differ from archaic C++?

"We know better now. Learn from the past. Don't do that" - Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Modern C++ is a set of techniques for programming C++. That's all that it is. It's not trendy and it's not buzzword compliant - indeed, may it never be so. Many of the techniques that make up modern C++ share common themes, such as pushing the appearance of errors as far away from runtime as possible. But there's no single principle that distinguishes modern techniques from archaic techniques, because the set of modern techniques was not selected for compliance to any single principle. (For example, "keep sharp things away from the programmer". Which sounds like a good idea until you need to slice a steel sheet in half.) Instead, the set of modern techniques was selected for effectiveness. Many factors contribute to (or inhibit) a technique's effectiveness. Among the many factors are expressiveness and safety. Something is expressive when you can say a lot of things with it easily. Something is safe when it would basically require complete ignorance or intentional stupidity to misuse, rather than a momentary lapse of attention or a failure to precisely reason out every single consequence of an action.

The Fundamental Theorem Of Arithmetic states that every integer greater than 1 has a unique factorization into primes. There are fundamental theorems of algebra and calculus too, but not of computer science. Which means that I can propose that the Fundamental Theorem Of Computer Science is that every computer can compute everything computable. (You may know this more formally as the Church-Turing Thesis.) "Every computer" means every computer worthy of the name, no matter how weird its architecture (universal Turing machine, two-stack machine, lambda calculus, RAM machine, etc.). It therefore follows that every programming language worthy of the name is capable of expressing anything said in any other programming language.

However, the Fundamental Theorem Of Software Engineering is even more important to programmers. Namely:

Computers are astonishingly big, fast, precise, and intolerant of error. Programmers, who are uniformly human, have minds that are astonishingly small, slow, imprecise, and tolerant of error. Hilarity ensues.

As a result, some programming techniques are better than others at getting programmers and computers to play nicely together. Not all programming techniques are created equal. Over the long history of C++ and the longer history of programming in general, people have tried lots of things. Lots and lots of things. Some of them are good, and some of them suck.

It's time for definitive answers. What is modern C++? It consists of techniques (including tools like the STL, idioms like SFINAE, and styles) that have proven themselves over time to be good at fighting the Fundamental Theorem Of Software Engineering. This is a battle, Fred Brooks tells us, that can never be won, although there is plenty of ground to be gained. (I would add that it can certainly be lost - finding examples is an exercise best left to the reader. I would also add that the Fundamental Theorem Of Software Engineering, like psychohistory, remains valid only while all the sentient players are human.)

How does modern C++ differ from archaic C++? I'll point out three ways.

First, modern C++ is growing as programmers discover new techniques for expressing concepts within C++. (C++ is a big language. So big, in fact, that people keep finding novel ways of combining its features to create useful and powerful machinery.) Modern C++ is also changing as programmers discover weaknesses in techniques that used to be the state of the art and proceed to overcome those weaknesses. Archaic C++ doesn't really change. It's stuck in the OOP mindset of the 1980s (back when being object-oriented was buzzword compliant). It grows only insofar as more lousy code is written in it.

Second, because archaic C++ has remained static, it has missed out on over a decade of developments - experience gained, libraries written, languages standardized, and techniques invented. (Template metaprogramming was discovered in 1994 by Erwin Unruh, for example.) Modern C++ has learned from those developments.

And third, modern C++'s techniques are better. They really are! Just as plows in agriculture were developed and improved over millennia as technology improved and people gained experience with them through trial, chance, error, and success, people have tried all sorts of things in programming and in C++. Long ago, people tried to implement based object containers (see C++ FAQs, Second Edition FAQ 28.08). They were the state of the art in that primitive time. And they sucked! They sucked. They really, really did. We know better now - STL containers, iterators, and algorithms are better machinery. I compare them to Asimov's nuclear shear for good reasons.

"There is no 'one right way' to design and build all systems.... Please remember that just because a technique worked for you last year and for one project, it does not follow that it will work unmodified for someone else or for a different project. It is most important to keep an open mind" - Bjarne Stroustrup, The C++ Programming Language, Special Edition

This fact is so important that it appears in the index of The C++ Programming Language, Special Edition under "one right way". Modern C++ is not the One Right Way. It's not even One Way. It is an expanding and evolving Set Of Ways. Modern C++ techniques are not applicable to every single field - specific examples include embedded and scientific programming, although modern C++ has been used in those fields and has shown some promise. Modern C++ has no presence whatsoever in certain other fields (e.g. web applets, though thankfully they seem to have lost their buzzword aura).

However, like C, C++ is a general purpose programming language. C's original domain was that of a system programming language, encompassing the compilers, operating systems, and other components that serve as the foundation for all other software to rest upon. C++'s current domain is that of a system programming language and an application programming language. That is a huge domain, which includes not only all of the applications that run on personal computers (I suppose that these are called client applications now), but all of the applications that run on servers as well. Servers, you see, are black boxes - bits go in and bits come out, and no one really cares what goes on inside of them as long as they work (properly, cheaply, quickly, etc.). The Fundamental Theorem Of Computer Science implies that C++ can be used on servers, and its general purpose nature combined with its deep expressiveness is a great strength there.

Modern C++ is therefore applicable to a vast domain of projects. Although there is no One Right Way to design and build all systems, for each system some techniques will be better than others. Modern C++, being a large and diverse set of powerful, expressive, and elegant programming techniques, is usually not only applicable but highly suited to solving problems within its massive domain. By learning, understanding, applying, and improving techniques from modern C++, you can become an extremely effective programmer and you can advance the state of the art. We haven't discovered everything that there is to be discovered, you know.

Books

I'm working on this section. Yes, I know that this page is not actually that useful yet.

Hello, World!

I'm not going to attempt to write a comprehensive introduction to C++'s basic features here. Books already exist for that purpose. In any event, few people seem to have trouble with learning how to use variables and loops. Traditionally, the first C++ program that one writes is called "Hello, World!".

"The only way to learn a new programming language is by writing programs in it. The first program to write is the same for all languages... This is the big hurdle; to leap over it you have to be able to create the program text somewhere, compile it successfully, load it, run it, and find out where your output went. With these mechanical details mastered, everything else is comparatively easy" - Brian W. Kernighan and Dennis M. Ritchie, The C Programming Language, Second Edition

This was written a very long time ago (today, "load" and "run" are not separate steps), but it is still very much true. Learning how to write "Hello, World!" is very dependent on what compiler, operating system, and so forth you use. Indeed, K&R2 does not mention the subhurdle of installing a compiler. My MinGW Distro tries to make it simpler for new programmers to get a compiler installed and running on Windows. Then they can learn how to compile "Hello, World!".


http://nuwen.net/14882.html (updated 8/2/2005)
Stephan T. Lavavej
Home: stl@nuwen.net
Work: stl@microsoft.com
This is my personal website. I work for Microsoft, but I don't speak for them.