Квалификаторы типов

Квалификаторы const, volatile и restrict предостовляют дополнительную информацию о переменных, перед именами которых они стоят.

const

Объекты типа const не могут быть изменены программой во время её выполнения. Кроме того, объект, адресуемый с помощью указателя, который определён как const, также не может быть модифицирован. Компилятор волен поместить переменную этого типа в память, предназначенную только для чтения (read-only mem — ROM). Переменная, определённая как const, получит своё значение либо из явной инициализации, либо по средством применения аппаратно-зависимых методов.

Копировать
const int a = 10;

Если функция-член класса модифицирована кв. типа const, то она не может изменять объект вызвавший эту функцию.

Копировать
class my {
	void fl() const;
	const void sl();
}

volatile

Модификатор volatile сообщает компилятору, что значение переменной может быть изменено средствами, задаными в програме неявным образом. Например, адрес глобальной переменной можно передовать системной прцедуре отсчёта времени и обновлять после каждого тиканья системных часов. В этом случае содержимое переменной изменяеться без выполнения какиж-либо явных операторов присваивания в программе. Это очень важный момент, поскольку компиляторы иногда автоматически оптимизируют определённые выражения, исходя из предположения, что содержимое переменной не изменяеться внутри этого выражения. Однако мод. volatile не допускает выполнения операций по оптимизации программного кода в тех редких случаях, когда это предположение не оправдано.

restrict

В версию С99 добавлен квалификатор типа restrict, который применяется только к указателям. Указатель с атрибутом restrict является изначально единственным средством, позволяющим получить доступ к объекту, на который он указывает. Доступ к этому объекту с помощью другого указателя возможен только в том случае, если второй указатель основан на первом. Таким образом, доступ к объекту ограничивается выражениями, основанными на restrict-квалифицированном указателе. Указатели, определенные с помощью квалификатора restrict, используются, главным образом, как параметры функций или для указания на память, выделенную с помощью функции malloc().

Если указатель квалифицирован с помощью ключевого слова restrict, компилятор имеет шанс лучше оптимизировать определенные типы программы на том основании, что restrict-указатель является единственным средством доступа к объекту. Например, если функция задает два параметра-указателя, квалифицированных как restrict, компилятор может предположить, что эти указатели отсылают к различным объектам(которые не перекрываются). Рассмотрим следующий пример использования квалификатора restrict (который стал классическим), а именно — функцию memcpy(). В версии С89 и языке C++ ее прототип имеет следующий вид.

Копировать
void *memcpy(void *strl, const void *str2, size_t размер);

В описании функции memcpy() отмечается, что если объекты, адресуемые параметрами str1 и str2, перекрываются, то поведение этой функции не определен(), Таким образом, функция memcpy() гарантированно работает только с неперекрывающимися объектами.

В версии С99 квалификатор restrict можно использовать для явного заявления в прототипе функции memcpy() о том, что в версии С89 и языке C++ приходится разъяснять словами. Вот как выглядит прототип функции memcpy() в версии С99.

Копировать
void *memcpy(void * restrict str1, const void * restrict str2, size_t размер);

Квалифицируя параметры с помощью ключевого слова restrict, этот прототип явно утверждает, что они указывают на неперекрывающиеся объекты.