Type qualifiers extend our control over variable behaviour. There are four type qualifiers in C: const
, volatile
, restrict
, and _Atomic
(C89, 89, 99, 11, respectively). Only the first two are available in C++.
const
The most common is the const
qualifier, meaning the variable is constant and cannot be changed later in the program. Note that for pointers, there’s two different ways it’s handled.
- For
const int *p = x
, we can change what it’s pointing to but not change the value inside its address, i.e.,*p = 30
may spit out a compiler error. - For
int *const p
, we can’t modify what it’s pointing to but we can change the value inside the address. Very confusing!
When we take a function input that doesn’t change, we should use a const
for safety — if it doesn’t need to change, then any code we write that changes it will cause a compile-time error (a big hint we’re doing something wrong).
We can also set methods as const
:
In cases like this, the object’s members won’t be able to change instead.
volatile
The volatile
specifier tells the compiler not to optimise anything associated with the variable, especially because its value may change outside of the compiler’s detection. There are a few important use cases of this, including when we interface with hardware that changes the value itself (as opposed to within the program).
In Nios and ARM, using
volatile
tells the compiler to useldwio
andstwio
instructions instead ofldw
andstw
.
This essentially asks the operating system not to look at the cache for this data, but instead a connected I/O device.
restrict
The restrict
specifier is used on pointers, and is used to tell the compiler that the pointer is the only access to the object it points to, i.e., we cannot get to the pointer value any other way.
This is especially relevant with pointer based functions (like those in stdlib.h or string.h). For string processing functions, this is an important optimisation tool.