October 2008 C++ Standards Committee Mailing - New C++0x Working Paper, More Concurrency Papers Approved

Wednesday, 08 October 2008

The October 2008 mailing for the C++ Standards Committee was published today. This is a really important mailing, as it contains the latest edition of the C++0x Working Draft, which was put out as a formal Committee Draft at the September 2008 meeting. This means it is up for formal National Body voting and comments, and could in principle be the text of C++0x. Of course, there are still many issues with the draft and it will not be approved as-is, but it is "feature complete": if a feature is not in this draft it will not be in C++0x. The committee intends to fix the issues and have a final draft ready by this time next year.

Concurrency Papers

As usual, there's a number of concurrency-related papers that have been incorporated into the working draft. Some of these are from this mailing, and some from prior mailings. Let's take a look at each in turn:

N2752: Proposed Text for Bidirectional Fences
This paper modifies the wording for the use of fences in C++0x. It is a new revision of N2731: Proposed Text for Bidirectional Fences, and is the version voted into the working paper. Now this paper has been accepted, fences are no longer tied to specific atomic variables, but are represented by the free functions std::atomic_thread_fence() and std::atomic_signal_fence(). This brings C++0x more in line with current CPU instruction sets, where fences are generally separate instructions with no associated object. std::atomic_signal_fence() just restricts the compiler's freedom to reorder variable accesses, whereas std::atomic_thread_fence() will typically also cause the compiler to emit the specific synchronization instructions necessary to enforce the desired memory ordering.
N2782: C++ Data-Dependency Ordering: Function Annotation
This is a revision of N2643: C++ Data-Dependency Ordering: Function Annotation, and is the final version voted in to the working paper. It allows functions to be annotated with [[carries_dependency]] (using the just-accepted attributes proposal) on their parameters and return value. This can allow implementations to better-optimize code that uses std::memory_order_consume memory ordering.
N2783: Collected Issues with Atomics
This paper resolves LWG issues 818, 845, 846 and 864. This rewords the descriptions of the memory ordering values to make it clear what they mean, removes the explicit qualification on the std::atomic_xxx constructors to allow implicit conversion on construction (and thus allow aggregate-style initialization), and adds simple definitions of the constructors for the atomic types (which were omitted by accident).
N2668: Concurrency Modifications to Basic String
This has been under discussion for a while, but was finally approved at the September meeting. The changes in this paper ensure that it is safe for two threads to access the same std::string object at the same time, provided they both perform only read operations. They also ensure that copying a string object and then modifying that copy is safe, even if another thread is accessing the original. This essentially disallows copy-on-write implementations since the benefits are now severely limited.
N2748: Strong Compare and Exchange
This paper was in the previous mailing, and has now been approved. In the previous working paper, the atomic compare_exchange functions were allowed to fail "spuriously" even when the value of the object was equal to the comparand. This allows efficient implementation on a wider variety of platforms than otherwise, but also requires almost all uses of compare_exchange to be put in a loop. Now this paper has been accepted, instead we provide two variants: compare_exchange_weak and compare_exchange_strong. The weak variant allows spurious failure, whereas the strong variant is not allowed to fail spuriously. On architectures which provide the strong variant by default (such as x86) this would remove the need for a loop in some cases.
N2760: Input/Output Library Thread Safety
This paper clarifies that unsynchronized access to I/O streams from multiple threads is a data race. For most streams this means the user is responsible for providing this synchronization. However, for the standard stream objects (std::cin, std::cout, std::cerr and friends) such external synchronization is only necessary if the user has called std::ios_base::sync_with_stdio(false).
N2775: Small library thread-safety revisions
This short paper clarifies that the standard library functions may only access the data and call the functions that they are specified to do. This makes it easier to identify and eliminate potential data races when using standard library functions.
N2671: An Asynchronous Future Value: Proposed Wording
Futures are finally in C++0x! This paper from the June 2008 mailing gives us std::unique_future<>, std::shared_future<> and std::promise<>, which can be used for transferring the results of operations safely between threads.
N2709: Packaging Tasks for Asynchronous Execution
Packaged Tasks are also in C++0x! This is my paper from the July 2008 mailing, which is the counterpart to N2671. A std::packaged_task<F> is very similar to a std::function<F> except that rather than returning the result directly when it is invoked, the result is stored in the associated futures. This makes it easy to spawn functions with return values on threads, and provides a building block for thread pools.

Other Changes

The biggest change to the C++0x working paper is of course the acceptance of Concepts. There necessary changes are spread over a staggering 14 Concepts-related papers, all of which were voted in to the working draft at the September 2008 meeting.

C++0x now also has support for user-defined literals (N2765: User-defined Literals (aka. Extensible Literals (revision 5))), for default values of non-static data members to be defined in the class definition (N2756: Non-static data member initializers), and forward declaration of enums (N2764: Forward declaration of enumerations (rev. 3)).

Get Involved: Comment on the C++0x Draft

Please read the latest C++0x Working Draft and comment on it. If you post comments on this blog entry I'll see that the committee gets to see them, but I strongly urge you to get involved with your National Body: the only changes allowed to C++0x now are in response to official National Body comments. If you're in the UK, contact me and I'll put you in touch with the relevant people on the BSI panel.

Posted by Anthony Williams
[/ cplusplus /] permanent link
Tags: , , ,

| Stumble It! stumbleupon logo | Submit to Reddit reddit logo | Submit to DZone dzone logo

Comment on this post

If you liked this post, why not subscribe to the RSS feed RSS feed or Follow me on Twitter? You can also subscribe to this blog by email using the form on the right.

2 Comments

Hello Anthony, one question and one suggestion relatred to threading.

Is it true that void this_thread::interruption_point() is not adopted by C++x0? I think it should because it enables cooperative interruption of task (single-thread, thread-pool).

I suggest that packaged_task catches and transfers (via future) all std-exceptions (runtime_error, etc.) + if supported even the thread_interrupted exception.

best regards, Oliver

by Oliver Kowalke at 20:16:41 on Saturday, 22 November 2008

The section on explict template member specialization does not explicitly state that when specialising a member function one needs to specialise all the other member functions as well. i.e. template class specialisation.

I was really hoping that finally we would be able to have a template type overloading mechanism where we could just specify all the "special case" member function overrides alongside the generic template member definitions.

I constantly find myself in a situations that the return type of a member function depends on the template parameter, but the function name and parameter types are the same. The code in the member function is quite specific to the template parameter e.g. Series<T>::derivative(double) need to work for both double and complex<double>, but the vast majority of the other member function are the same.

Along this line I would also like to see template parameter based switch & if statements which include and exclude blocks of code based on the template type parameter. (similar to the way #ifdefs are used). e.g

switch <T> case: double T = 1.0; case <complex<double>> T.real = 1.0; T.imag = 2.0; break; }

all this would minimise code duplication associated with template specialisation.

by serle at 12:32:44 on Wednesday, 01 April 2009

Add your comment

Your name:

Your URL:

Email address:

Person or spambot?

Your comment: