C++0x

C++1x loses Concepts

Bjarne Stroustrup and Herb Sutter have both reported on the ISO C++ meeting in Frankfurt a week ago, in which the much-heralded feature "concepts" were removed from C++1x.

Concepts are a powerful feature aimed at improving overloading (basically, removing the extra work in using things like iterator categories) and moving type checking up the ladder so that more reasonable error messages can be produced when a developer passes in the wrong type (think a single error line instead of multiple pages of template crap). Apparently the feature was a lot less solid than most of us thought, with a huge amount of internal arguing within the committee on a lot of the fundamental features of it. It seems that while most agreed concepts were a good idea, nobody could agree on how to implement them.

I'm definitely disappointed by this, but I'm also glad they chose to remove concepts instead of further delaying the standard, or worse putting out a poorly designed one. Instead, it seems like there is hope for a smaller C++ update to come out in 4-5 years that adds a more well thought out concepts feature. There are plenty of other C++1x language features to be happy about for though, like variadic templates, rvalue references, and lambda functions!

You may notice I've been saying C++1x here instead of C++0x—that's because it's pretty obvious to everyone now that we won't be getting the next C++ standard in 2009, but more likely 2011 or 2012. Just in time for the end of the world!

Visual C++ 2010 Beta 1

Visual Studio 2010 Beta 1 was released yesterday for MSDN subscribers. Probably the most anticipated release in a while for C++ developers, 2010 is Microsoft's attempt to give C++ first-class support, something which hasn't been seen since Visual Studio 6.0.

Update: downloads are now available for non-MSDN subscribers.

On the compiler side of things, we get partial C++0x support in the form of lambda expressions, rvalue references, auto, decltype, and static assert. The features are piled on with an improved TR1 library—finally including the much requested stdint.h and cstdint headers, but still lacking inttypes.h.

Also included is the Parallel Patterns Library, a new task-based concurrency library that makes heavy use of the C++0x features for a nice modern design. I mentioned before that on Windows 7 this will make use of a User-mode scheduled thread pool so it should be really efficient. Unfortunately given its proprietary nature I'm not sure how much use it will get.

The first thing you will notice on the IDE side is the inline error checking. Something we've enjoyed while editing C# for some time, we now get the red squiggly lines when an error is found. It works fairly well, but support for lambda expressions has not been written yet.

Intellisense has markedly improved since 2008. Using advanced C++ or a Boost library no longer guarantees it breaking. It has worked with nearly all the C++ I've thrown at it so far.

You can also see an External Dependencies virtual folder added to your project source, which is dynamically filled with all the files Intellisense will scan. I've found it is not terribly useful, though, because even with small projects the header count increases rapidly enough to make the virtual folder become an unintelligible mess.

The problem is only aggravated by libraries like Boost, which have hundreds of headers organized nicely in folders. Putting them into a single virtual folder just doesn't work.

This release also marks the move to the extensible MSBuild system for C++ projects, which aims to provide functionality similar to GNU make in an XML format.

Perhaps the most obvious change for the overall IDE is that the main UI is now done entirely in WPF. It sounded like a decent plan at first but I'm not too happy with it now. Minor differences from the way native controls behave can be pretty annoying, and the five to twenty second load time makes it less useful for opening random .cpp files when 2008 would load them in one or two seconds.

C++0x is now feature complete

Herb Sutter posts to tell us C++0x is now feature complete. There will now be about a year of bugfixing and clarification, but that’s it: all the features are now known, and their interfaces are solid barring any bugs being found. This means compilers can finally start implementing C++0x at full speed without too much worry of surprises.

The Committee Draft is not yet available, but it is about the same as the September 2008 Working Draft.

GCC 4.3, C++0x preview

GCC 4.3 came out a couple weeks ago, and I finally got time to give its experimental C++0x support a go. Specifically, I was interested in two features of it: variadic templates and rvalue references.

There is one prime example of what these two features are awesome for: perfect forwarding. Take a memory pool. You might have something like this:

class pool {
   void* alloc();

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

But that is hardly satisfactory. What if you want to construct T with an argument?

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 function to handle passing an arg. Better, but still not very great. What if you want to pass it multiple arguments?

C++ has very few problem that can’t be worked around in a relatively straitforward way. Unfortunately, this is one of those problems. The current solution most library developers employ will involve some really nasty preprocessor hacks to generate separate functions for 1, 2, 3, up to maybe 10 or 15 arguments. So, how do we solve this?

Enter variadic templates, the new C++ feature built specifically to solve this. Here is an updated pool class that takes any number of arguments:

class pool {
   void* alloc();

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

Pretty simple! Those ellipses will expand into zero or more args. Great – we’re almost there. But we still have a problem here: what happens if the constructor for T takes some arguments as non-const references? This construct function will try to pass them as const references, resulting in a compile error. We can’t have it pass args as non-const references, because then if you pass it an rvalue—such as a temporary—it will generate another compile error as rvalues can only be bound to const references.

This is where the second part of our pool upgrades come in: rvalue references.

class pool {
   void* alloc();

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

We’ve finally got our solution. That double-reference looking thing is the new syntax for rvalue references. This construct implements perfect forwarding: calling construct<foo>(a, b, c, d) will behave exactly as if we had called the constructor directly via new(alloc()) T(a, b, c, d).

This works because Args is a templated type that will resolve to references and const references if it needs to. One problem I have yet to figure out how to solve is a constructor where you know the type you want, and want to accept any reference 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 reference: I just want the construction of m_b to be as efficient as possible so that it can use move semantics when you pass it an rvalue. So far the only way I can find to do it is with two separate constructors, which could mean a lot of code duplication on something less trivial than this example.

C++0x work progressing

A bit delayed, but I just found the results of the October 2007 C++ meeting. In it, they voted in several really nice things for the C++0x draft: