Вся суть restrict
заключается в том, чтобы обещать доступ через один указатель, а не псевдоним другого. Тем не менее, есть примеры, когда перекрывающиеся адреса памяти не подразумевают псевдонимы. Например:
int* arr_ptr0 = &arr[0];
int* arr_ptr1 = &arr[1];
for (int i=0;i<10;++i) {
*arr_ptr0 = *arr_ptr1;
arr_ptr0 += 2;
arr_ptr1 += 2;
}
Дело в том, что эти указатели на самом деле действительно указывают на перекрывающуюся память! Для этого конкретного примера такие руководства, как это говорит, например:
Это действительно. . . указывать на один и тот же объект массива при условии, что диапазон элементов, доступ к которым осуществляется через один из указателей, не перекрывается с диапазоном элементов, к которым осуществляется доступ через другой указатель.
Мой вопрос: Какая степень детализации "элементов"?
Например, предположим, что у меня есть массив типа struct Foo
. Нужно ли мне гарантировать, что я не буду обращаться к одному и тому же диапазону элементов (Foo
s), даже если части, к которым я обращаюсь, не пересекаются? Вот простой скалярный пример:
struct Foo { int i; float f; };
void f(struct Foo*restrict foo0, struct Foo*restrict foo1) {
foo0->i = 6;
foo1->f = 19.0f;
}
void g(struct Foo* foo) {
f(foo,foo); /* problem? */
}
Вы можете столкнуться с подобными проблемами с указателями на разные типы (например, char
против int
), но, возможно, приведенный выше пример структуры более нагляден.
ptr1[a] .. ptr1[b]
(a ‹ b) иptr2[c] .. ptr2[d]
(c ‹ d) и любой из адресов в первом диапазоне совпадает с любым из адресов во втором диапазоне, ограничение ограничения нарушается. - person Jonathan Leffler   schedule 20.09.2014restrict
. - person R.. GitHub STOP HELPING ICE   schedule 20.09.2014