Monday, January 9, 2012

The time_t's Are a-Changin' (into system_clock Time Points)

2011 came and went, but left us with a new ISO C++ standard, codenamed C++11. I've looked for an updated edition of "The C++ Programming Language", or at least some other full-sized book on the subject, but the best I've been able to find at the time of writing this is Scott Meyers' "Presentation Materials: Overview of the New C++", as recommended by Herb Sutter. It's not perfect (it doesn't cover everything, it does have a few bugs, and it's not completely up to date with C++11), but it's good and required reading for serious C++ developers.

Probably the single most important change in the language itself is the addition of rvalue references, with all that comes along with them, such as move semantics and perfect forwarding.

I'm happy to see auto_ptr, with it's freak copy-is-move semantics, go away to be replaced by unique_ptr. I'm also very happy to see added support for custom deleters in the new _ptr classes: that makes the problem of resource acquisition and release that I've written about here easier to handle.

Anything involving callbacks is now easier, thanks to function. And good riddance to exception specifications and the (template-related) export keyword that almost no C++ compiler implemented anyway!

There's now support for writing multithreaded applications, but semaphore classes are conspicuously missing. You can simulate a semaphore with condition_variables, but that misses out on native OS semaphore support. Why semaphores didn't make it into C++11, I can't imagine. And why no sockets in C++11? They're as ubiquitous and necessary today as mutexes.

I'm disappointed to see that a subtle feature that would have solved a lot of issues did not get into C++11: the compiler could (and in my humble opinion, should) make all destructors of classes with at least one virtual member function virtual as well. A class with a virtual member function is most likely meant to be inherited from, and in case the destructor releases some resource, destroying a derived object through a base class pointer is very dangerous, unless the base class' destructor is virtual. Making it virtual by default in such a case would thus greatly improve safety.

There are, of course, plenty of other new things in C++11: variadic templates, Java-like inherited (and delegating) constructors, the auto keyword (guess what that does), range for() statements, and so on.

You might like to read Bjarne Stroustrup's C++11 FAQ, where, in response to "what do you think of C++11?", he states that he's "still an optimist". C++ started as "C with classes", making it easier than stuffing pointers-to-function into structs. Then, it got templates, adding generic programming to its object-oriented and procedural capabilities. Then, Lisp-like functional programming got added on top of the generic programming support with the popularity of template meta-programming. While it's still true that, with C++ (11 or otherwise), you don't pay for what you don't use, it's also still true that you have to know about almost everything in order not to accidentally shoot yourself in the foot. And everything is getting bigger. C++ is one of the areas of software development where "junior" and "senior programmer" are heavily meaningful terms. If your company can't afford at least a senior mentor to 2-3 junior C++ programmers, you might be better off using plain C, Java or C#.

C++11 improves some things, leaves others out, and complicates yet others (e.g. container::cbegin()/container::cend() added for auto). If you're comfortable with C++98, there's still plenty of time to get acquainted with it's features (and quirks), since most compilers don't yet fully support it. It'll be some time until C++11 gets fully implemented by compiler vendors, and it is very likely that some of it's features will never be implemented by some of them (just like C++98's template export keyword). This is what GCC 4.5.3 had to say to me today (on my Gentoo Linux system):

$ g++ future.cpp
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/thread:35:0,
from future.cpp:2:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/c++0x_warning.h:31:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.

0 comments: