При использовании ограничения указателя в C, в порядке изменить переменную с помощью его начального идентификатора?

StackOverflow https://stackoverflow.com/questions/3936060

  •  30-09-2019
  •  | 
  •  

Вопрос

При использовании A. restrict Указатель в C, это нормально, чтобы изменить переменную, используя его начальный Идентификатор? Например:

int foo = 0;

int * restrict fooPtr = &foo;
++(*fooPtr);                   // Part 1: foo is 1 (OK)

++foo;                         // Part 2: foo is 2 (Is this OK?)

int * fooPtr2 = &foo;
++(*fooPtr2);                  // Part 3: foo is 3 (BAD: You shouldn't access via a second pointer)

... я изменил ценность фюра через фюра после restrict фуоптр был создан.

Часть 1. выглядит хорошо для меня. Я запутался о Часть 2. Отказ И от того, о чем я понимаю restrict, Часть 3 это плохо (компилятор позволяет это, но его поведение не определено, и это зависит от программиста не делать этого).

Это было полезно?

Решение

Нет, часть 2 не в порядке.

Конкретная часть стандарта составляет 6,7,3.1/4. Этот раздел довольно плотный, и делает несколько повторных читаний, но P - это ограниченный указатель, и X - какой-то объект, который он используется для доступа, и который изменен. Так что в вашем примере p fooPtr и х это foo. Отказ Потом:

Каждая другая Lvalue используется для доступа к стоимости X, также имеет свой адрес на основе P.

«На основании» определяется в предыдущем абзаце, и суммировать, Lvalue foo делает нет есть свой адрес, основанный на ограничении P., чтобы правило нарушено при доступе к объекту foo через свое имя.

Часть 3 не в порядке для точно такой же причины, Lvalue *fooPtr2 Не основывается на P, а также используется для доступа к X.

Я говорю «не в порядке» - быть точным, комбинация 1 + 2 провоцирует неопределенное поведение, как и комбинация 1 + 3. До тех пор, пока вы на самом деле не доступа к объекту через ограниченный указатель, ни одно из определений ограничения «ударов». Если вы хотите, чтобы вы могли удалить часть 1, сохранить неиспользуемый ограниченный указатель, а затем 2 и 3 было бы в порядке.

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

Да, «Часть 3» - неопределенное поведение. С спецификации C99 (6.7.3, пункт 7):

Объект, который обращается через ограничение-квалифицированный указатель, имеет специальную ассоциацию с этим указателем. Эта ассоциация определена в 6.7.3.1 ниже, требует, чтобы все доступ к этому использованию объекта, прямо или косвенно, стоимость этого конкретного указателя.

Я бы сказал # 2 плохо. Например, компилятор может оптимизировать, загрузка значения в * FOOPTR в реестр, а затем записывать, что значение записи обратно в Foo еще позже - после вашего ++ Foo, чтобы The ++ Foo потерян.

Предполагая, что все части вашего вопроса происходят в одном блоке, не в порядке для доступа к значению foo напрямую (часть 2) или для доступа к нему через другой указатель (часть 3):

  • 6.7.3.1 Формальное определение ограничения

Каждая другая Lvalue используется для доступа к стоимости X, также имеет свой адрес на основе P.

Формальное определение restrict Довольно трудно следовать (по крайней мере для меня), однако следующее менее формальное описание также из стандарта суммирует его довольно хорошо (по крайней мере, для этого случая):

Объект, который обращается через ограниченный указатель, имеет специальную ассоциацию с этим указателем. Эта ассоциация, определенная в 6.7.3.1 ниже, требует, чтобы все обращались к этому объекту, непосредственно или косвенно, стоимость этого конкретного указателя.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top