Является ли квалификатор ограничения C транзитивным через указатели?

Является ли ключевое слово/определитель C restrict транзитивным через несколько уровней косвенности указателя?

Например, учитывая следующий фрагмент:

struct Bar {
    int b;
};

struct Foo
{
    struct Bar* bar;
};

int examineFoos(struct Foo* restrict foo1, struct Foo* restrict foo2)
{
    foo1->bar->b = 1;
    return foo2->bar->b;
}

int main(void)
{
    struct Bar bar = { 0 };
    struct Foo foo1 = { .bar = &bar };
    struct Foo foo2 = { .bar = &bar };
    int val = examineFoos(&foo1, &foo2);
    return val;
}

Вызывает ли это неопределенное поведение и может val == 0, потому что оно нарушает restrict при доступе к bar, или это действительный код, и мы всегда получаем val == 1, потому что restrict не применяется транзитивно через указатель bar?

Я сомневаюсь, что это имело бы смысл с точки зрения удобства использования, если бы оно было «транзитивным», как вы предлагаете.

Eugene Sh. 22.04.2024 21:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
1
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Условия restrict для foo1 и foo2 не накладывают никаких ограничений на использование структур, на которые указывают foo1->bar и foo2->bar, как показано ниже.

Требования, предъявляемые к программе restrict, указаны в C 2018 6.7.3.1 4. Эти требования применяются только «Если L используется для доступа к значению объекта X, который он обозначает, и X также модифицируется (любыми способами), », где L — это lvalue, для которого &L основано на P, обозначенном как ограниченный указатель для ввода T во время выполнения связанного блока B. Основание указано в 6.7.3.1 3:

В дальнейшем выражение-указатель E называется основанным на объекте P, если (в какой-то точке последовательности выполнения B перед вычислением E) модифицируется P, чтобы указать на копию объекта массива, на который оно ранее указывало. изменит значение E.

Указатели с ограничением — это foo1 и foo2. Подумайте, может ли foo1->bar или foo2->bar основываться на foo1 или foo2. Другими словами, если E равно foo1->bar или foo2->bar, изменится ли его значение, если будет произведена модификация, описанная выше?

Предположим, в различных точках тела examineFoos (блока B) мы делаем копии структур, на которые указывают foo1 и foo2, а затем меняем foo1 и foo2, чтобы они указывали на соответствующие копии. Будет ли значение foo1->bar после этого вмешательства таким же, как и раньше? Да, потому что значение foo1->bar определяется байтами, которые его представляют, и эти байты были скопированы. Аналогично, foo2->bar будет иметь то же значение.

Следовательно, foo1->bar и foo2->bar не основаны на foo1 или foo2, поэтому спецификация restrict не накладывает никаких требований относительно их использования для доступа к объектам, на которые они указывают.

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