Является ли «* p = ++ (* q)» неопределенным когда p и q указывают на один и тот же объект?

после прочтения о точках последовательности я узнал, что i = ++ i не определено.

Так как насчет этого кода:

int i;
int *p = &i;
int *q = &i;
 *p = ++(*q);           // that should also be undefined right?

Скажем так если инициализация p и q зависит от некоторого (сложного) условия. И они могут указывать на один и тот же объект, как в предыдущем случае. Что случится? Если он не определен, какие инструменты мы можем использовать для обнаружения?

Редактировать: Если два указателя не должны указывать на один и тот же объект, можем ли мы использовать ограничение C99? Что означает «строгий»?

12
задан Nyan 26 October 2011 в 22:26
поделиться

4 ответа

Да, это неопределенное поведение — у вас есть две модификации объекта без точки следования между ними. К сожалению, автоматическая проверка этого очень сложна - лучшее, что я могу придумать, это добавить assert(p != q) прямо перед этим, что, по крайней мере, даст чистую ошибку времени выполнения, а не что-то еще хуже. Проверка этого во время компиляции в общем случае неразрешима.

12
ответ дан 2 December 2019 в 07:20
поделиться

Лучший инструмент, чтобы не обнаруживать, но в первую очередь избегать этого, — это использовать передовые методы программирования. Избегайте побочных эффектов и выполняйте не более одной записи за одно задание. В этом нет ничего плохого

*q += 1;
*p = *q;
4
ответ дан 2 December 2019 в 07:20
поделиться

Глава 5 Выражения

Пункт 4:

Если не указано иное, порядок вычисления операндов отдельных операторов и подвыражений отдельных выражений, а также порядок, в котором имеют место побочные эффекты. , не указано. Между предыдущей и следующей точкой следования сохраненное значение скалярного объекта должно быть изменено не более одного раза при вычислении выражения. Кроме того, доступ к предыдущему значению должен осуществляться только для определения сохраняемого значения. Требования настоящего параграфа должны выполняться для каждого допустимого порядка подвыражений полного выражения; в противном случае поведение не определено.

[ Example:
  i = v[i ++];           / / the behavior is undefined
  i = 7 , i++ , i ++;    / / i becomes 9
  i = ++ i + 1;          / / the behavior is undefined 
  i = i + 1;             / / the value of i is incremented
—end example ]

В результате возникает неопределенное поведение:

int i;
int *p = &i;
int *q = &i;
*p = ++(*q);   // Bad Line

В «Плохой строке» скалярный объект «i» обновляется более одного раза во время вычисления выражения. Тот факт, что доступ к объекту «i» осуществляется косвенно, не меняет правила.

2
ответ дан 2 December 2019 в 07:20
поделиться

Выражение такое же, как i=++i. Единственный инструмент, который может обнаружить это, это ваша голова. В C с властью приходит ответственность.

2
ответ дан 2 December 2019 в 07:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: