A Note on Keywords
The C committee prefers not to create new keywords in the user namespace, as it is generally expected that each revision of C will avoid breaking older C programs. By comparison, the C++ committee (WG21) prefers to make new keywords as normal-looking as the old keywords. For example, C++11 defines a new
thread_local keyword to designate static storage local to one thread. C11 defines the new keyword as
_Thread_local. In the new C11 header
<threads.h>, there is a macro definition to provide the normal-looking name:
#define thread_local _Thread_local
In these articles, I will assume that you include the appropriate headers, so I will show the normal-looking names.
thread_local Storage Class
thread_local storage class provides static storage that is unique to each new thread, and is initialized before the thread begins execution. However, there are no safeguards to prevent you from taking the address of a
thread_local variable and passing it to other threads; what happens next is implementation-defined (i.e., not portable). Each thread has its own copy of
Threads are Optional
C11 has designated several features as optional. For example, if the implementation defines a macro named
_ _STDC_NO_THREADS_ _, then it will presumably not provide a header named
<threads.h> nor any of the functions defined therein.
Politics, Design, and Incomplete Information
As a general rule, WG21 entrusts Bjarne Stroustrup with the overall design-and-evolution responsibility; do an online search for "camel is a horse designed by committee" to understand the reasons for this approach. However, there is one design principle that motivates both WG14 and WG21: Don't leave room for a more-efficient systems-programming language underneath our language (C or C++).
Some participants (call them "Group A") expect that atomic data will remain a seldom-used specialty, but others (call them "Group B") believe that atomic data will become a crucial feature, at least for a systems-programming language.
Over the past decades, various higher-level languages have been built based on C (Java, C#, Objective C, and of course, C++) and subsets-or-supersets based on C++ (such as D and Embedded C++). Many companies that participate in WG14 and WG21 have made decisions regarding the languages in which their apps will be written. Those companies that chose C++ as their upper-level app language (call them "Group C") are often content for C to be stabilized (or for WG21 to control its standardization), whereas companies that chose other languages (call them "Group D") sometimes regard C as a crucial foundation under their upper-level app language.
With this much background, I can give an account of the evolution of atomics in C11. The design of atomics in C++11 made crucial use of templates, such that
atomic<T> is the simple and universal way of getting the atomic version of any type
T, even if
T is a
struct type; and
atomic<T*> retains all the compile-time type information of whatever
T* points to. However, for several years, the C design used only the several dozen named types (such as
atomic_llong shown above). One advantage of the named-type approach is that it requires no changes to the compiler itself; it can be implemented in a library-only solution, which invokes system-dependent intrinsic functions at the very lowest level. However, the named-type approach precludes creating an atomic for any C
struct (no matter how small) or for a
T* pointer (for a general
T that is known to the compiler). Largely due to the influence of Group B and Group D opinions within WG14, a decision was made to require a C11 compiler to recognize an atomic
T for any type
There was also a subsequent controversy within WG14 about the compiler syntax for specifying an atomic
T. One approach ("atomic-parenthesis") was motivated by compatibility with C++: Let
_Atomic(T) be the syntax for designating an atomic
T. Then that same source program could be compiled as C++ simply by defining one macro:
#define _Atomic(T) atomic<T>
The other side of the controversy preferred to create a new type-qualifier (analogous to the C99 treatment of
_Complex); using this syntax ("atomic-space"), the type atomic
T would be written as
"_Atomic T". A program written using that syntax could not directly be compiled as C++ (without making use of compatibility macros that would look essentially like the atomic-parenthesis approach).
Both sides of this issue agreed that, once a team commits to modifying the compiler for this feature of C11, it's a relatively minor amount of incremental work to implement both the atomic-parenthesis syntax and the atomic-space syntax. In the end, that's the position that prevailed in WG14. In the meantime, the price of that decision is that only the named-type approach is available today (until compilers implement the C11 syntaxes), and the most-vocal Group C participants can grumble about the decisions of WG14 creating incompatibilities with C++.
Getting the C11 Standard
The new standard can be ordered at webstore.ansi.org (search for "ISO/IEC 9899:2011"). It is now available in PDF, but it costs $285 (as does the 2011 revision of C++). Once these standards have been adopted as U.S. National Standards by ANSI (within a few months), that price will drop to about $30.
You can periodically check this section of this page, where I will update the status of the availability of the draft. Or, if you fill out a web form, you will be notified by email when the C11 and C++11 standards become available from ANSI.
Dr. Thomas Plum is Vice President of Technology and Engineering at Plum Hall Inc., and is a member of the C and C++ committees that developed C11 and C++11. He can be reached at [email protected]. The author gratefully acknowledges helpful suggestions from Pete Becker, the project editor of the 2011 C++ standard.