Одной из самых важных новинок, введенных Стандартом С99, является квалификатор типа restrict (ограниченный). Этот квалификатор применяется только к указателям. Указатель, определенный с квалификатором типа restrict[1], изначально является единственным средством, с помощью которого можно получить доступ к указываемому объекту. Доступ к объекту с помощью другого указателя возможен лишь тогда, когда этот второй указатель основан на первом. Таким образом, доступ к объекту возможен только для выражений, составленных на основе указателя с квалификатором типа restrict. Такие указатели в основном используются как параметры функций или для указания памяти, распределенной с помощью malloc(). Квалификатор типа restrict семантики программы не меняет.
Если указатель квалифицирован с помощью квалификатора типа restrict, то компилятор может лучше оптимизировать некоторые программы, зная, что указатель с квалификатором типа restrict является единственным средством доступа к объекту. Например, если функция имеет два параметра в виде указателей с квалификатором типа restrict, то компилятор может допустить, что указатели указывают на разные (причем неперекрывающиеся!) объекты. Проанализируем, например, то, что стало классическим примером применения restrict — определение функции memcpy(). В С89 у нее имеется следующий прототип:
void *memcpy(void *cmp1, const void *cmp2, size_t размер);
В описании memcpy() сказано, что если объекты, на которые указывают cmp1 и cmp2, перекрываются, то поведение этой функции непредсказуемое. Таким образом. memcpy() гарантированно будет работать только с неперекрывающимися объектами.
В С99 можно использовать restrict, чтобы в прототипе memcpy() явно указать то, что в С89 приходится дополнительно объяснять словами. Вот прототип memcpy() в С99:
void *memcpy(void * restrict cmp1, const void * restrict cmp2, size_t размер);
Квалифицируя cmp1 и cmp2 с помощью квалификатора типа restrict, в прототипе явно утверждается, что они указывают на неперекрывающиеся объекты.
Из-за преимуществ, которые может принести использование квалификатора типа restrict, в С99 он был добавлен в прототипы многих библиотечных функций, определенных еще в С89.
[1]Указатель, определенный с квалификатором типа restrict, называется также restrict-квалифицированным указателем или указателем, квалифицированным как restrict.