Heise Developer: GoingNative 2012 — Gegenwart und Zukunft von C++

For you German speakers out there, my sixth Heise Developer article, “GoingNative 2012 — Gegenwart und Zukunft von C++” just went live on Heise’s site.

It’s a sum-up of the GoingNative 2012 conference that happened on Feb 2nd-3rd. There won’t be an English translation later, since it’d be outdated by the time it appeared. The talks are in English, and you can download them all from Microsoft’s Channel9 page, though.

From the article:

Die Qualität der Vorträge war durchweg hoch, wenn auch Nichtmuttersprachler einigen Vortragenden nur schwer folgen konnten. Die Konferenz macht Lust auf ein Jahr mit mehr C++-Konferenzen als seit 1999 üblich. Besonders hängen blieben das Versprechen auf schnelle Adoption des neuen Standards, auch von Clang und Microsoft, und der Versuch, die C++-Standardbibliothek in den nächsten Jahren massiv zu erweitern.

GoingNative12 @ KDAB, Berlin

For everyone interested in C++11, and as suggested by Herb Sutter, KDAB will show the live stream of the GoingNative12 C++ conference in it’s training facilities at Tempelhofer Ufer 11 in Berlin this Thursday and Friday (Feb 2nd and 3rd). The show is scheduled to run from 18:30 to 02:15 (CET) each day. We invite everyone to join us, but please drop us a note at berlin(at)kdab.com so we can plan ahead.

Private Practice: Taming Templates

I’ve started a new column, Private Practice, that looks at existing implementations and examines them.

The first Private Practice article, Taming Templates, examines techniques to control template code bloat. There’s nothing particularly earth-shattering in there, but I noticed that a lot of people don’t seem to be aware of the fact that templates can cause a lot of duplicated code, so I thought I’d write about it.

Even if they haven’t been released under the Private Practice banner, the following articles also fit that category well:

Heise Developer: Gelernt aus Fehlern

For you German speakers out there, Heise Developer just published a re-issue of my C++0x overview article from the 2009 Programmieren Heute, called “Gelernt aus Fehlern“.

Compared to the print version, we’ve updated the content in some places, such as spending less time on the removal of concepts and more about the adoption of the new standard, as well as turning the Top 10 into a Top 11 to celebrate the new standard 🙂

From the article:

Die spannendste Frage wird sein, wie schnell sich C++11 gegen seinen Vorgänger C++98 wird durchsetzen können. Es war in den vergangenen zwei Dekaden regelmäßig notwendig, C++-Neuerungen konservativ einzusetzen, da Compiler den Standard nur zögerlich umgesetzt haben. […] Hier muss sich die C++-Gemeinde umgewöhnen. Neuerungen wie Lambdas und auto machen C++11 zu einer deutlich produktiveren Sprache, als C++98 es war. Es gilt nun, diese Produktivitätssteigerung im Alltag auch zu nutzen, um gegen Java und .NET zu bestehen. Ein weiteres Jahrzehnt der Zersplitterung und Inkompatibilität könnte die momentan exzellente Ausgangsposition von C++ schnell wieder zunichte machen.

Hope you like it.

C++98 Support Costs Extra!

I should note, right up front, that this post reflects my personal opinion and not that of my employer. In particular, KDAB currently does not require extra payment for C++98 support, even though, as this post will make abundantly clear, I personally wouldn’t mind if it did :).

So, the new C++ standard is finalised and voted on unanimously. Does that mean that we’ll have another decade of C++ incompatibilities ahead of us?

My answer to that is: That depends on us.

Will we adopt C++11 faster than C++98? Our compilers do. Will we make use of the new productivity gains (auto, range-for, lambdas, …) or will we continue to castrate our code to work with 15-year-old compilers? The answers of the majority of C++ programmers will determine how the next decade goes for all of us.

In this post, I’ll argue (strongly) for dropping C++98 support asap, and using C++11 to the fullest possible extent in all our projects. This includes dropping support for compilers and platforms that don’t (yet) support C++11 to the extent required by a particular project instead of #ifdefing our way around it, as we (as an industry) have done for the past 30 years. Will these compilers and platforms be left out in the cold? Not really: they will have older versions of libraries and programs to support them. But yes, newer versions will require an up-to-date C++ compiler.

Is this realistic? I think it is.

Essentially, we have this situation already now. Many projects require fairly recent versions of libraries, precisely because 1) there’s not much point in supporting older versions, and 2) supporting many versions of one library with the same code-base is fairly expensive. I’ve tried. Gpgme++ theoretically supports gpgme’s that can be considered stone-aged. Has anyone ever tested this? Hmmm… How many Mac applications still support OS X 10.2? 10.3? 10.4? Half of the web doesn’t work anymore on KDE 3.5’s Konqueror.

Then why should we be so conservative when it comes to C++, the very core of what we work with? It’s not even customer-visible. Why do we accept an STL shipping in 2011 that is basically unchanged from the mid-1990s? Why do we #ifdef our way around MSVC6 problems in 2011? Why do we care about the quirks of GCC 3.3, or heaven forbid, 2.95?

My new-year’s resolution (ok, it’s a bit early, but hey): stop it!

C++11 support in C++ compilers now is much stronger than C++98 support was in 1998 in the then-C++-compilers. I fully expect every C++ compiler to have caught up on final C++11 with its next major release, except for source-code invisible changes like the new memory model. I want Qt 5 to require a C++11 compiler. I want KDE 5 to require a C++11 compiler. I will lobby inside KDAB to do the same.

Why? Because I’m a programmer, and we’re lazy.

I want to use auto. If you make me type std::map<std::string,std::string>::const_iterator instead of auto, it’s more work, less fun, so you should need to pay extra.

I want to use lambdas. If you make me write

struct ByName : std::binary_function<Foo,Foo,bool> {
    result_type operator()( const Foo & lhs, const Foo & rhs ) const {
        return lhs.name() < rhs.name() ;

instead of [](const Foo &lhs, const Foo &rhs) { return lhs.name() < rhs.name() ; }, it’s more work, less fun, so you should need to pay extra.

C++11 is a much more productive language than C++98. We as an industry can, however, only reap that productivity gain if we stop throwing C++ productivity out of the window by the bucket-load in the hopeless pursuit of compatibility with non-standard implementations. The worst offender, Microsoft, has seen the light. Their current compilers are very standards-compliant, and actively maintained. I hope that Apple won’t be the next blocker: By choosing Clang over GCC for—apparently—political reasons (GCC 4.2 was the last GCC with GPLv2), they have lost at least one year of C++11 support that GCC and VC are ahead of Clang. Let’s hope Clang catches up soon.

[[EDIT 2011-09-21: If you think that VC isn’t implementing C++11 fast enough, you can make yourselves heard here: http://visualstudio.uservoice.com, in particular here and here.]]

[[EDIT 2012-03-30: Microsoft has announced that the VC++ compiler will have a faster release cycle than Visual Studio. That makes me hope that we’ll see a “reasonably conforming” (Sutter) VC++ a long time before 2014. Also, Clang++ 3.1 has caught up a lot with GCC (http://clang.llvm.org/cxx_status.html#cxx11, 3.1 currently shows up as “SVN”); it seems tooling will indeed not be the problem, after all.]]

Understand the Qt Containers: The Data

This is just a short heads-up to those that have asked for quantitative measurements. I’ve begun updating “Understand the Qt Containers” with a section on data.

As of now, the memory and append performance is in. I’ll re-run the iteration test over the night once more (I’ve detected an anomaly that I’d like the verify first), and re-add them again, when done.

Effective Qt: Understand the Qt Containers

The third of my Effective Qt columns, “Understand the Qt Containers“, just went live on my site.

If you know me, you will know what awaits you there 🙂 I hope I have not disappointed you. That said, this is just a first part. I plan to eventually extend it to cover more containers (currently, just QVector and QList), and give more data and assembler code for the containers I’ve already described.

These are the guidelines this item covers:

  • Remember that QList has nothing to do with std::list, and QSet has nothing to do with std::set.
  • Be aware of the two Qt container APIs, Qt-ish and STL-compatible, and avoid mixing their use in the same project.
  • Familiarise yourself with the STL containers and the additional features they offer.
  • Prefer member-swap over assignment wherever possible to express move semantics. Use C++11 rvalue move semantics if the class and the compiler support them.
  • [[EDIT 2011-08-25: new]] Always use constBegin()/constEnd() (cbegin()/cend()) when assigning the result to a const_iterator.
  • Avoid modifying a container (remove/insert elements) while iterating. If you have to, use an STL algorithm, such as one of the std::remove() family.
  • Prefer the STL-compatible iterators over the Java-style ones.
  • If you do use the Java-style iterators, avoid using the mutating ones.
  • Prefer to use const references as the first argument of Q_FOREACH, unless the element type is customarily passed by value.
  • Familiarise yourself with BOOST_FOREACH, and the additional features it offers.
  • Declare your enums and QFlags as Q_PRIMITIVE_TYPE if there’s a chance they will be held in Qt containers.
  • Declare your value-types Q_MOVABLE_TYPE if there’s a chance they will be held in Qt containers.
  • Don’t change the classification of a type if you need to maintain binary compatibility.
  • Prefer vector (std or Q) over QList.
  • Avoid QList<T> where T is not declared as either Q_MOVABLE_TYPE or Q_PRIMITIVE_TYPE or where sizeof(T) != sizeof(void*) (remember to check both 32 and 64-bit platforms).
  • [[EDIT 2011-08-16: new]] Avoid using vectors of types for which Qt APIs customarily use QList, and for which QList is not inefficient.

Hope you enjoy!