C++0x

C++1x loses Concepts

Bjarne Strous­trup and Herb Sut­ter have both re­ported on the ISO C++ meet­ing in Frank­furt a week ago, in which the much-her­alded fea­ture "con­cepts" were re­moved from C++1x.

Con­cepts are a pow­er­ful fea­ture aimed at im­prov­ing over­load­ing (ba­si­cally, re­mov­ing the extra work in using things like it­er­a­tor cat­e­gories) and mov­ing type check­ing up the lad­der so that more rea­son­able error mes­sages can be pro­duced when a de­vel­oper passes in the wrong type (think a sin­gle error line in­stead of mul­ti­ple pages of tem­plate crap). Ap­par­ently the fea­ture was a lot less solid than most of us thought, with a huge amount of in­ter­nal ar­gu­ing within the com­mit­tee on a lot of the fun­da­men­tal fea­tures of it. It seems that while most agreed con­cepts were a good idea, no­body could agree on how to im­ple­ment them.

I'm def­i­nitely dis­ap­pointed by this, but I'm also glad they chose to re­move con­cepts in­stead of fur­ther de­lay­ing the stan­dard, or worse putting out a poorly de­signed one. In­stead, it seems like there is hope for a smaller C++ up­date to come out in 4-5 years that adds a more well thought out con­cepts fea­ture. There are plenty of other C++1x lan­guage fea­tures to be happy about for though, like vari­adic tem­plates, rvalue ref­er­ences, and lambda func­tions!

You may no­tice I've been say­ing C++1x here in­stead of C++0x—that's be­cause it's pretty ob­vi­ous to every­one now that we won't be get­ting the next C++ stan­dard in 2009, but more likely 2011 or 2012. Just in time for the end of the world!

Visual C++ 2010 Beta 1

Vi­sual Stu­dio 2010 Beta 1 was re­leased yes­ter­day for MSDN sub­scribers. Prob­a­bly the most an­tic­i­pated re­lease in a while for C++ de­vel­op­ers, 2010 is Mi­crosoft's at­tempt to give C++ first-class sup­port, some­thing which hasn't been seen since Vi­sual Stu­dio 6.0.

Up­date: down­loads are now avail­able for non-MSDN sub­scribers.

On the com­piler side of things, we get par­tial C++0x sup­port in the form of lambda ex­pres­sions, rvalue ref­er­ences, auto, de­cltype, and sta­tic as­sert. The fea­tures are piled on with an im­proved TR1 li­brary—fi­nally in­clud­ing the much re­quested stdint.h and cst­dint head­ers, but still lack­ing int­types.h.

Also in­cluded is the Par­al­lel Pat­terns Li­brary, a new task-based con­cur­rency li­brary that makes heavy use of the C++0x fea­tures for a nice mod­ern de­sign. I men­tioned be­fore that on Win­dows 7 this will make use of a User-mode sched­uled thread pool so it should be re­ally ef­fi­cient. Un­for­tu­nately given its pro­pri­etary na­ture I'm not sure how much use it will get.

The first thing you will no­tice on the IDE side is the in­line error check­ing. Some­thing we've en­joyed while edit­ing C# for some time, we now get the red squig­gly lines when an error is found. It works fairly well, but sup­port for lambda ex­pres­sions has not been writ­ten yet.

In­tel­lisense has markedly im­proved since 2008. Using ad­vanced C++ or a Boost li­brary no longer guar­an­tees it break­ing. It has worked with nearly all the C++ I've thrown at it so far.

You can also see an Ex­ter­nal De­pen­den­cies vir­tual folder added to your pro­ject source, which is dy­nam­i­cally filled with all the files In­tel­lisense will scan. I've found it is not ter­ri­bly use­ful, though, be­cause even with small pro­jects the header count in­creases rapidly enough to make the vir­tual folder be­come an un­in­tel­li­gi­ble mess.

The prob­lem is only ag­gra­vated by li­braries like Boost, which have hun­dreds of head­ers or­ga­nized nicely in fold­ers. Putting them into a sin­gle vir­tual folder just doesn't work.

This re­lease also marks the move to the ex­ten­si­ble MS­Build sys­tem for C++ pro­jects, which aims to pro­vide func­tion­al­ity sim­i­lar to GNU make in an XML for­mat.

Per­haps the most ob­vi­ous change for the over­all IDE is that the main UI is now done en­tirely in WPF. It sounded like a de­cent plan at first but I'm not too happy with it now. Minor dif­fer­ences from the way na­tive con­trols be­have can be pretty an­noy­ing, and the five to twenty sec­ond load time makes it less use­ful for open­ing ran­dom .cpp files when 2008 would load them in one or two sec­onds.

C++0x is now feature complete

Herb Sut­ter posts to tell us C++0x is now fea­ture com­plete. There will now be about a year of bug­fix­ing and clar­i­fi­ca­tion, but that’s it: all the fea­tures are now known, and their in­ter­faces are solid bar­ring any bugs being found. This means com­pil­ers can fi­nally start im­ple­ment­ing C++0x at full speed with­out too much worry of sur­prises.

The Com­mit­tee Draft is not yet avail­able, but it is about the same as the Sep­tem­ber 2008 Work­ing Draft.

GCC 4.3, C++0x preview

GCC 4.3 came out a cou­ple weeks ago, and I fi­nally got time to give its ex­per­i­men­tal C++0x sup­port a go. Specif­i­cally, I was in­ter­ested in two fea­tures of it: vari­adic tem­plates and rvalue ref­er­ences.

There is one prime ex­am­ple of what these two fea­tures are awe­some for: per­fect for­ward­ing. Take a mem­ory pool. You might have some­thing like this:

class pool {
   void* alloc();

   template<typename T>
   T* construct() { return new(alloc()) T; }
};

But that is hardly sat­is­fac­tory. What if you want to con­struct T with an ar­gu­ment?

class pool {
   void* alloc();

   template<typename T>
   T* construct() { return new(alloc()) T; }

   template<typename T, typename ArgT>
   T* construct(const ArgT &arg) { return new(alloc()) T(arg); }
};

So we add a new func­tion to han­dle pass­ing an arg. Bet­ter, but still not very great. What if you want to pass it mul­ti­ple ar­gu­ments?

C++ has very few prob­lem that can’t be worked around in a rel­a­tively strait­for­ward way. Un­for­tu­nately, this is one of those prob­lems. The cur­rent so­lu­tion most li­brary de­vel­op­ers em­ploy will in­volve some re­ally nasty pre­proces­sor hacks to gen­er­ate sep­a­rate func­tions for 1, 2, 3, up to maybe 10 or 15 ar­gu­ments. So, how do we solve this?

Enter vari­adic tem­plates, the new C++ fea­ture built specif­i­cally to solve this. Here is an up­dated pool class that takes any num­ber of ar­gu­ments:

class pool {
   void* alloc();

   template<typename T, typename Args...>
   T* construct(const Args&... args) { return new(alloc()) T(args...); }
};

Pretty sim­ple! Those el­lipses will ex­pand into zero or more args. Great – we’re al­most there. But we still have a prob­lem here: what hap­pens if the con­struc­tor for T takes some ar­gu­ments as non-const ref­er­ences? This con­struct func­tion will try to pass them as const ref­er­ences, re­sult­ing in a com­pile error. We can’t have it pass args as non-const ref­er­ences, be­cause then if you pass it an rvalue—such as a tem­po­rary—it will gen­er­ate an­other com­pile error as rval­ues can only be bound to const ref­er­ences.

This is where the sec­ond part of our pool up­grades come in: rvalue ref­er­ences.

class pool {
   void* alloc();

   template<typename T, typename Args...>
   T* construct(Args&&... args) {
      return new(alloc()) T(std::forward(args)...);
   }
};

We’ve fi­nally got our so­lu­tion. That dou­ble-ref­er­ence look­ing thing is the new syn­tax for rvalue ref­er­ences. This con­struct im­ple­ments per­fect for­ward­ing: call­ing construct<foo>(a, b, c, d) will be­have ex­actly as if we had called the con­struc­tor di­rectly via new(alloc()) T(a, b, c, d).

This works be­cause Args is a tem­plated type that will re­solve to ref­er­ences and const ref­er­ences if it needs to. One prob­lem I have yet to fig­ure out how to solve is a con­struc­tor where you know the type you want, and want to ac­cept any ref­er­ence type:

struct foo {
   foo(const bar &b) : m_b(b) {}
   foo(bar &&b) : m_b(std::move(b)) {}

   bar m_b;
};

I don’t care if b is a lvalue or rvalue ref­er­ence: I just want the con­struc­tion of m_b to be as ef­fi­cient as pos­si­ble so that it can use move se­man­tics when you pass it an rvalue. So far the only way I can find to do it is with two sep­a­rate con­struc­tors, which could mean a lot of code du­pli­ca­tion on some­thing less triv­ial than this ex­am­ple.

C++0x work progressing

A bit de­layed, but I just found the re­sults of the Oc­to­ber 2007 C++ meet­ing. In it, they voted in sev­eral re­ally nice things for the C++0x draft: