Elements of Modern C++ Style

image

As I’m getting ready to resume writing a few new (or updated) Guru of the Week Items for the C++11 era, I’ve been looking through the wonderful features of C++11 and analyzing just which ones will affect the baseline style of how I write modern C++ code, both for myself and for publication.

I’ve gathered the results in a short page. Here’s the intro:

Elements of Modern C++ Style

“C++11 feels like a new language.” – Bjarne Stroustrup

The C++11 standard offers many useful new features. This page focuses specifically and only on those features that make C++11 really feel like a new language compared to C++98, because:

  • They change the styles and idioms you’ll use when writing C++ code, often including the way you’ll design C++ libraries. For example, you’ll see more smart pointers, and functions that return big objects by value.
  • They will be used so pervasively that you’ll probably see them in most code examples. For example, virtually every five-line modern C++ code example will say “auto” somewhere.

Use the other great C++11 features too. But get used to these ones first, because these are the pervasive ones that show why C++11 code is clean, safe, and fast – just as clean and safe as code written in any other modern mainstream language, and with C++’s traditional to-the-metal performance as strong as ever.

Like Strunk & White, this page is deliberately focused on brief summary guidance. It is not intended to provide exhaustive rationale and pro/con analysis; that will go into other articles.

I hope you find it useful.

Apologies in advance if some of the code snippets are odd or missing template argument lists. Let me know and I’ll fix any I missed. I think I restored them all (again), but am still fighting my tools, which keep sporadically eating angle-bracket lists. Someday someone will integrate good code authoring in a good editor for a good blogging platform; today’s tools are at best “adequate.”

Garbage Collection Synopsis, and C++

Insert your favorite "stop the world" joke here.

In response to my note about John McCarthy’s inventing automatic (non ref-counted) garbage collection, rosen4obg asked:

OK, GC was invented half a century ago. When it is going to land in the C++ world?

Here’s a short but detailed answer, which links to illuminating reading and videos.

The Three Kinds of GC

The three major families of garbage collection are:

  1. Reference counting.
  2. Mark-sweep (aka non-moving) collectors, where objects are collected but live objects don’t move. This is what McCarthy first invented.
  3. Mark-compact (aka moving) collectors, where live objects are moved together to make allocated memory more compact. Note that doing this involves updating pointers’ values on the fly. This category includes semispace collectors as well as the more efficient modern ones like the .NET CLR’s that don’t use up half your memory or address space.

When I say “automatic GC” I mean #2 or #3.

GC and C++

C++ has always supported #1 well via reference counted smart pointers. Those are now standard in C++11 in the form of unique_ptr, shared_ptr, weak_ptr. C++98 had auto_ptr, but it was never great and has been deprecated.

C++ has long supported #2, but less formally because the products were nonstandard, conservative, and not as portable. The major prior art is the Boehm (later Great Circle and Symantec) mark-sweep garbage collector. The new C++11 standard has just added a minimal GC ABI to more formally bless such non-moving collectors; see Stroustrup’s GC FAQ for more.

C++ cannot support #3 without at least a new pointer type, because C/C++ pointer values are required to be stable (not change their values), so that you can cast them to an int and back, or write them to a file and back; this is why we created the ^ pointer type for C++/CLI which can safely point into #3-style compacting GC heaps. See section 3.3 of my paper A Design Rationale for C++/CLI for more rationale about ^ and gcnew.

Other GC Resources

For a wonderful 57-minute conversation on garbage collection by one of the world’s top GC experts, run don’t walk to the C9 “Inside Garbage Collection” interview with Patrick Dussud. Patrick wrote the .NET CLR’s GC, and it was far from his first; before that he had deep experience implementing Lisp runtimes, and I’m sure has forgotten more about GC than I’ll ever know. He’s also a great guy to work with.

For a great book on GC, I love Garbage Collection by Jones and Lins.

John McCarthy

image

What a sad, horrible month. First Steve Jobs, then Dennis Ritchie, and now John McCarthy. We are losing many of the greats all at once.

If you haven’t heard of John McCarthy, you’re probably learning about his many important contributions now. Some examples:

  • He’s the inventor of Lisp, the second-oldest high-level programming language, younger than Fortran by just one year. Lisp is one of the most influential programming languages in history. Granted, however, most programmers don’t use directly Lisp-based languages, so its great influence has been mostly indirect.
  • He coined the term “artificial intelligence.” Granted, however, AI has got a bad rap from being oversold by enthusiasts like Minsky; for the past 20 years or so it’s been safer to talk in euphemisms like “expert systems.” So here too McCarthy’s great influence has been less direct.
  • He developed the idea of time-sharing, the first step toward multitasking. Okay, now we’re talking about a contribution that’s pretty directly influential to our modern systems and lives.

But perhaps McCarthy’s most important single contribution to modern computer science is still something else, yet another major technology you won’t hear nearly enough about as being his invention:

Automatic garbage collection. Which he invented circa 1959.

No, really, that’s not a typo: 1959. For context, that year’s first quarter alone saw the beginning of the space age as Sputnik 1 came down at the end of its three-month orbit; Fidel Castro take Cuba; Walt Disney release Sleeping Beauty; The Day the Music Died; the first Barbie doll; and President Eisenhower signing a bill to enable Hawaii to become a state.

GC is ancient. Electronic computers with core memory were still something of a novelty (RAM didn’t show up until a decade or so later), machine memory was measured in scant kilobytes, and McCarthy was already managing those tiny memories with automatic garbage collection.

I’ve encountered people who think GC was invented by Java in 1995. It was actually invented more than half a century ago, when our industry barely even existed.

Thanks, John.

And here’s hoping we can take a break for a while from writing these memorials to our giants.

Your First C Program

As a tribute in honor of Dennis Ritchie’s passing, I’d like to invite you to share your thoughts in this post’s comments about your first C program – either the code if you remember it approximately, or a story about when you wrote it.

Here’s mine.

I wrote my first C program in 1988 as a lab assignment for a fourth-year course in computer graphics at the University of Waterloo. In the first day or two of the course, our prof gave us our first assignment: Write a program that displays and controls a 3D animated robot with moving head, arms, and legs. Successive assignments would let us swoop around him, controlling point of view and zoom with a mouse, and other nifty features, but the first assignment was just to get him on-screen and capable of a little basic motion.

Oh, and the program was to be written:

  • to run on one of the lab’s four brand-new SGI IRIS workstations (oh, here’s the manual);
  • using a custom UofW internal library (oh, here’s the manual);
  • in C (we assume you know it, use man to learn this compiler’s command line switches if you need to);

and it’s due in a few days. I can’t remember exactly now, but I think we had something like five days. After all, this was just a warm-up initial exercise for the course.

Here’s the thing: I had never used C. Never even seen it.

Oh, I’d used many different languages in my undergrad career, from Cobol to Pascal to Prolog to 6809 assembler and many points between, but just never C. Don’t get the wrong impression, C was already used widely at UofW at the time and most of the other undergrads in the class knew it, but by some freak of course selection combined with professor allocation I somehow had managed to come across pretty much everything but C so far for the first three years.

Fortunately, there was K&R.

Armed with K&R and a printed-out C tutorial, I had a few days to learn a new language (huh? whaddayamean #include? oh, okay…), an unfamiliar compiler, an unfamiliar graphics library, and the quirks of this particular flavor of Unix – to produce a working program in an unfamiliar domain with unfamiliar concepts (graphics). And only that last bit was the actual topic material for the course. The language, compiler, library, etc. was just uninteresting scaffolding you were expected to know or just pick up on the fly, don’t bother the professor with questions about those when you can look it all up yourself.

I don’t remember what mark I got on the assignment, but the code worked.

I was glad that C was easy to learn, and that its manual in the form of K&R was so clear to read and understand. Thanks again, Dennis.

2000 Interview: Dennis Ritchie, Bjarne Stroustrup, and James Gosling

Ritchie, Stroustrup, and Gosling

Dennis Ritchie gave very few interviews, but I was lucky enough to be able to get one of them.

Back in 2000, when I was editor of C++ Report, I interviewed the creators of C, C++, and Java all together:

The C Family of Languages: Interview with Dennis Ritchie, Bjarne Stroustrup, and James Gosling

This article appeared in Java Report, 5(7), July 2000 and C++ Report, 12(7), July/August 2000.

Their extensive comments — on everything from language history and design (of course) and industry context and crystal-ball prognostication, to personal preferences and war stories and the first code they ever wrote — are well worth re-reading and remarkably current now, some 11 years on.

As far as I know, it’s the only time these three have spoken together. It’s also the only time a feature article ran simultaneously in both C++ Report and Java Report.

Grab a cup of coffee, fire up your tablet, and enjoy.

Dennis Ritchie

dmr (Dennis Ritchie)

What a sad week.

Rob Pike reports that Dennis Ritchie also has passed away. Ritchie was one of the pioneers of computer science, and a well-deserved Turing winner for his many contributions, notably the creation of C — by far the most influential programming language in history, and still going strong today.

Aside: Speaking of “still going strong,” this is a landmark week for the ISO Standard C Programming Language as well. Just a couple of days ago, the new C standard passed what turned out to be its final ballot,[*] and so we now have the new ISO C11 standard. C11 includes a number of new features that parallel those in C++11, notably a memory model and a threads/mutexes/atomics concurrency library that is tightly aligned with C++11. The new C standard should be published by ISO in the coming weeks.

[*] ISO rules are that if you pass the penultimate ballot with unanimous international support, you get to skip the formality of the final ballot and proceed directly to publication.

Bjarne Stroustrup made an eloquent point about the importance of Ritchie’s contributions to our field: “They said it couldn’t be done, and he did it.”

Here’s what Bjarne meant:

Before C, there was far more hardware diversity than we see in the industry today. Computers proudly sported not just deliciously different and offbeat instruction sets, but varied wildly in almost everything, right down to even things as fundamental as character bit widths (8 bits per byte doesn’t suit you? how about 9? or 7? or how about sometimes 6 and sometimes 12?) and memory addressing (don’t like 16-bit pointers? how about 18-bit pointers, and oh by the way those aren’t pointers to bytes, they’re pointers to words?).

There was no such thing as a general-purpose program that was both portable across a variety of hardware and also efficient enough to compete with custom code written for just that hardware. Fortran did okay for array-oriented number-crunching code, but nobody could do it for general-purpose code such as what you’d use to build just about anything down to, oh, say, an operating system.

So this young upstart whippersnapper comes along and decides to try to specify a language that will let people write programs that are: (a) high-level, with structures and functions; (b) portable to just about any kind of hardware; and (c) efficient on that hardware so that they’re competitive with handcrafted nonportable custom assembler code on that hardware. A high-level, portable, efficient systems programming language.

How silly. Everyone knew it couldn’t be done.

C is a poster child for why it’s essential to keep those people who know a thing can’t be done from bothering the people who are doing it. (And keep them out of the way while the same inventors, being anything but lazy and always in search of new problems to conquer, go on to use the world’s first portable and efficient programming language to build the world’s first portable operating system, not knowing that was impossible too.)

Thanks, Dennis.

ISO C++11 Published

ISO

ISO has now published the new C++11 standard and issued a press release: English here, French here.

Thanks again to everyone who made this happen, most especially Bjarne Stroustrup, who not only invented the language three decades ago, but as Evolution Working Group subgroup chair continues to be an active guiding force in its continued evolution. C++11 wouldn’t be the same without the wisdom of his experience and his able direction.

Preemptive note for those who are concerned that ISO charges money for the final official text of the standard: There are, or will soon be, several good options ranging from cheap to free. First, all of the C++11 working drafts and papers are freely available at the WG21 committee page, including near-final drafts of the standard, except only for the final text where ISO asserts copyright. Second, as national bodies ratify and publish the standard themselves, you will be able to purchase the final text of the standard from them instead of ISO if you prefer (the only difference will be the cover page); for example, ANSI published the previous C++ standard in PDF form for $18, which is much less than most C++ books.

ISO’s bulletin text follows:

ISO PRESS RELEASE / COMMUNIQUE DE PRESSE DE L’ISO (VERSION FRANCAISE CI-APRES)

C++ language gets high marks on performance with new ISO/IEC standard

C++, one of the most popular programming languages used in everything from Web browsers to 3D video games, has been fully updated and published as, ISO/IEC 14882:2011, Information technology – Programming languages – C++.

C++11’s improvements incorporate many of the best features of managed languages. Its new features extend C++’s traditional strengths of flexibility and efficiency.

MORE: http://www.iso.org/iso/pressrelease.htm?refid=Ref1472

Follow ISO on Twitter http://www.twitter.com/isostandards

Join us on Facebook: http://www.facebook.com/isostandards

Le langage C++ remarqué pour sa performance grâce à une nouvelle norme ISO/CEI

C++, un des langages de programmation les plus populaires utilisé dans tout, du moteur de recherche Internet aux jeux vidéo en 3D, a fait l’objet d’une mise à jour complète, publiée dans le document ISO/CEI 14882:2011, Technologies de l’information – Langages de programmation – C++.

Les améliorations apportées à C++11 intègrent un bon nombre des points forts des langages managés. De nouvelles fonctionnalités viennent rehausser la souplesse et l’efficacité de C++.

PLUS D’INFO: http://www.iso.org/iso/fr/pressrelease.htm?refid=Ref1472

Suivre l’ISO sur Twitter http://www.twitter.com/isostandards

Joignez-nous sur Facebook: http://www.facebook.com/isostandards

Why no container-based algorithms?

A few minutes ago, a colleague on another team asked:

I really enjoyed your talk on Modern C++ from the Build conference, and have a quick question: Could there be a simpler syntax – something like:

foreach(collection, lambda_function) // or some other syntactic name for “foreach”

which would expand to

for_each(begin(collection), end(collection), lambda_function)

Same for find_if, etc.

This was considered and is desirable. In today’s C++ it’s easy to do for some algorithms, but not others. The main problem is overloading, which needs better template support (i.e., C++0x concepts which were proposed but didn’t make it) and/or adding enable_if.

Briefly, the basic problem is that you already have predicate overloads for some algorithms:

template<typename Iter>
void sort( Iter, Iter ); // 1

template<typename Iter, typename Pred>
void sort( Iter, Iter, Pred ); // 2

So far, so good. But what we want to add is:

template<typename Container>
void sort( Container& ); // 3

template<typename Container, typename Pred>
void sort( Container&, Pred ); // 4

And 4 is difficult to distinguish cleanly from 1 today. Both are match-anything function templates taking two parameters, and 1 would be preferred by the language when the argument types are identical, but in common cases you encounter unfortunate effects. For example, Howard Hinnant points out that if you try to call sort with (say) an iterator and a const_iterator, if we had only 1 you’d get a reasonably clear error message, but now because 4 is able to match different parameter types the compiler will instead try to invoke 4, which isn’t at all close to the original intent, and you’ll get a deeply strange template error message somewhere in the bowels of 4’s implementation because it wasn’t expecting anything like an iterator for either parameter.

Of course, not all algorithms have this issue where there are already overloads with different numbers of parameters. I’m hopeful that the standard library will get range-based overloads of all standard algorithms that are enable_if’d to avoid the problem or can use concepts if those make it into a future standard.

Here’s what the enable_if workaround might look like (I haven’t actually tried this though):

template<typename Iter>
typename enable_if< !CallableWithBeginAndEnd< Iter >::value, void >::type
sort( Iter, Iter ); // 1

template<typename Iter, typename Pred>
void sort( Iter, Iter, Pred ); // 2

template<typename Container>
void sort( Container& ); // 3

template<typename Container, typename Pred>
typename enable_if< CallableWithBeginAndEnd<Container>::value, void >::type
sort( Container&, Pred ); // 4

WordPress.com expertise

I’m generally satisfied with the look and feel of this blog, but would like to tweak it in a few small ways to get a cleaner look, nicer formatting for code examples, and such.

If you or someone you know is familiar with WordPress.com blog customization, and is interested in a small project along these lines, please send me mail. Thanks.

Steve Jobs

Today our industry is much less than it was yesterday. We have lost one of the great innovators. Even more importantly, Steve Jobs’ family has lost a husband and brother and father, and our thoughts are with them.

What can be said that hasn’t been said? Steve has been arguably the single most influential driver and shaper of personal computing in every one of its five decades, from the 1970s to the 2010s. It’s obviously true for the 1970s (Apple, Apple ][) and 1980s (Mac). As for the 1990s, it should be enough that the Mac shaped essentially all of that decade’s desktop and notebook platforms, and icing on the cake that technologies pioneered at NeXT and Pixar so heavily influenced personal gaming and other personal computing. In the 2000s, suffice it to say that Steve put the personal  i  into modern computing and again transformed this industry, and other industries. Looking forward, absent some other world-changing event, it’s clear that the rest of the 2010s will see personal computing develop along the trail he and his teams have blazed already in this decade.

Here is a measure of a man’s impact: Imagine how different — how diminished — the world would be today if Steve had passed away ten years ago.

Makes our hearts fade a little, doesn’t it?

Now imagine how different — how much more — the world would be if Steve had lived another ten years.

Or another twenty. Or another fifty, as though what we have seen were but the first half of his life — and if the second half were not as a slowly aging, diminishing man, but with his health and strength and faculties as strong as ever for that much more time, a true fifty more years.

We are all cut down too soon.

Thanks, Steve.