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:

Fraction Fraction::exampleMethod(Fraction &rhs) const {
	// some code
}

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 use ldwio and stwio instructions instead of ldw and stw.

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.

See also