C11 supports four “type qualifiers” const (C89), volatile (C89), restrict (C99), and _Atomic (C11). So_Atomic is a type qualifier. In this blog post, you will learn what _Atomic keyword is and when you should use it.
So let’s get started.
_Atomic keyword:
The _Atomic keyword is introduced in C11. It is not only used as a type qualifier but also use as a type specifier. It means _Atomic is type qualifier and type specifier both.
Now you are thinking how is it possible?
Yes, it is possible due to their syntax. So let’s see the syntax of _Atomic in C,
_Atomic ( type-name ) (1) (since C11) _Atomic type-name (2) (since C11)
Where,
1)
_Atomic use as a type specifier
; this designates a new atomic type.
2)
_Atomic use as a type qualifier
; this designates the atomic version of type-name.
The compiler does not support atomic types or _Atomic type qualifier (including the <stdatomic.h> header) if the macro constant __STDC_NO_ATOMICS__
(C11) is defined by the compiler. You must remember that you only use the _Atomic keyword when the compiler supports it.
The header <stdatomic.h
> defines several macros and declares several types and functions for performing atomic operations on data shared between threads. Let’s see a few of them.
Typedef name | Full type name |
atomic_bool |
_Atomic _Bool |
atomic_char |
_Atomic char |
atomic_schar |
_Atomic signed char |
atomic_uchar |
_Atomic unsigned char |
atomic_short |
_Atomic short |
atomic_ushort |
_Atomic unsigned short |
atomic_int |
_Atomic int |
atomic_uint |
_Atomic unsigned int |
atomic_long |
_Atomic long |
atomic_ulong |
_Atomic unsigned long |
atomic_llong |
_Atomic long long |
atomic_ullong |
_Atomic unsigned long long |
atomic_char16_t |
_Atomic char16_t |
atomic_char32_t |
_Atomic char32_t |
_Atomic use as a type specifier:
If the _Atomic keyword is immediately followed by a left parenthesis, it is interpreted as a type specifier type qualifier. Like the below expression.
_Atomic ( type-name )
Where,
type name:
any type other than array type, a function type, an atomic type, or a cvr qualified type.
Example,
_Atomic(float) a; _Atomic(int) b;
_Atomic use as a type qualifier:
As we have discussed above it is also a type qualifier. But you should remember only to use _Atomic when your compiler supports it.
_Atomic type-name
Where,
type name:
any type other than array type, a function type.
Example,
// ptr1 is a pointer to an atomic const int _Atomic const int * ptr1; // ptr2 is a pointer to an int atomic const //Both ptr1 and ptr2 same const atomic_int * ptr2;