Большая часть того, что вы знаете, неверна!
const не гарантирует, что что-то не изменится за спиной компилятора. Все, что он делает, это останавливает вы от записи в это место. Возможно, что-то еще может записать в это место, поэтому компилятор не может предположить, что он постоянен.
Как уже говорили другие, ограничивающий квалификатор - это псевдонимы. На самом деле, во время первого раунда стандартизации C было предложено ключевое слово «noalias». К сожалению, предложение было довольно плохо написано - оно вызвало единственное время, когда Деннис Ричи включился в этот процесс, когда он написал письмо, в котором говорилось что-то о том, что «надо сойтись. Это не открыто для переговоров» «
Само собой разумеется, «noalias» не стал частью C. Когда пришло время попробовать еще раз, предложение было написано достаточно лучше, чтобы ограничение было включено в стандарт - и хотя noalias, вероятно, было бы более значимое название для него, это имя было настолько испорчено, что я сомневаюсь, что кто-нибудь даже подумывал попробовать его использовать.
В любом случае, основная цель restrict - сообщить компилятору, что псевдоним этого элемента не будет. Одной из причин этого является временное сохранение вещей в регистрах. Например, рассмотрим что-то вроде:
void f(int *a, int *b, int *c) {
for (int i=0; i<*a; i++)
*b += c[i];
}
Компилятор действительно хочет поместить i в регистр и загрузить * a в регистр, поэтому, когда приходит время решить, выполнять ли другую итерацию цикла, он просто сравнивает значения в этих регистрах друг с другом , К сожалению, он не может этого сделать - если кто-то, кто использовал эту функцию, был полностью сумасшедшим и вызывал ее с помощью a == b, каждый раз, когда он записывает * b внутри цикла, это новое значение также является значением * a - поэтому он должен читать * a из памяти на каждой итерации цикла, на случай, если тот, кто его вызвал, был совершенно безумным. Использование restrict сообщает компилятору, что он может генерировать код, предполагая, что a и b всегда будут различаться, поэтому запись в * a никогда не изменит * b (или наоборот).