Путаница в неопределенном поведении ограничивающего квалификатора

Я видел следующий пример на cppreference.

void f(int n, int * restrict p, int * restrict q)
{
    while(n-- > 0)
        *p++ = *q++; // none of the objects modified through *p is the same
                     // as any of the objects read through *q
                     // compiler free to optimize, vectorize, page map, etc.
}
void g(void)
{
    extern int d[100];
    f(50, d + 50, d); // OK
    f(50, d + 1, d); // Undefined behavior: d[1] is accessed through both p and q in f
}

В этом примере вызов f(50, d + 50, d); хорошо

Но я не понимаю, звоню f(50, d + 1, d); является неопределенным поведением. Зачем?

1 ответ

Решение

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

В f(50, d + 50, d);, p будет использоваться для изменения d[50] вплоть до d[99], а также q будет использоваться для доступа d[0] вплоть до d[49], Там нет перекрытия, так что все в порядке.

В f(50, d + 1, d);, p будет использоваться для изменения d[1] вплоть до d[50], а также q будет использоваться для доступа d[0] вплоть до d[49], Поскольку некоторые элементы (например, d[1]) изменены через p и прочитать qэто нарушение restrict Классификатор.

Другие вопросы по тегам