New Atomic Types
C11 defines a new _Atomic() type specifier. You can declare an atomic integer like this:
_Atomic(int) counter;
C++11 moves this declaration into the standard library:
#include <atomic> std::atomic<int> counter;
The C++ version has the advantage that it can be implemented without any compiler modification. It's possible to implement versions of these templates using inline assembly for each of the operations. A more efficient implementation will require some compiler support, typically in the form of a set of intrinsic functions.
You may wonder why you need explicit atomic types, when the GCC intrinsics just work on any pointer. There are two main reasons.
The first relates to portability. Some architectures have quite limited support for atomic operations. In the worst case, they may have no support at all, so every atomic operation will require a call into the kernel to suspend other threads while the operation takes place. More commonly, some architectures have limits on the size they support for atomic operations. They may only support 32-bit atomics, so operations on long long would not be allowed. They may only support a 1-bit operation, enough to support a lightweight mutex.
On any such platform, _Atomic(int) may be longer than int, including space for a guard — a mutex or similar. You probably won't come across any platforms where this is the case, but the standard permits it.
C++ is a bit more explicit. You can use any type in the std::atomic<> template. If you had a class HugeThing containing 1MB of data, you could expect std::atomic<HugeThing> to work for atomic updates. The implementation may protect things that large with a mutex, or in any other way it chooses.