Арифметические указатели, ссылающиеся на те же адреса - PullRequest
0 голосов
/ 15 октября 2019

Я немного пытаюсь понять следующую операцию:

B - переменная, Pt1 и Pt2 указывают на & B

enter image description here

Уменьшение производится после воздействия, поэтому по моей логике должно быть 68, но моя IDE дает мне 69, может кто-нибудь объяснить?

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 15 октября 2019

Стандарт С 6.5 6.5 дает такое загадочное объяснение этому явлению:

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

  • «Скалярный объект» в данном случае означаетВаша исходная переменная указывает на
  • «Вычисление значения» в этом случае отменяет ссылку на любой из указателей. Они указывают на одну и ту же переменную.
  • «Побочный эффект» в данном случае означает изменение переменной. И присвоение =, и оператор -- являются побочными эффектами.

Оператор присваивания не задает порядок вычисления своих операндов (6.5.16 "Оценка операндов не секвенирована".). Не указывается, происходит ли *Pt2 до или после *Pt1--.

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

Простой способ избежать этого -придерживайтесь этого правила:

Никогда не используйте операторы ++ или - вместе с другими операторами в одном выражении.

2 голосов
/ 15 октября 2019

Код, который вы дали, создает неопределенное поведение! Убирая аспект указателя, вы по существу делаете это:

B = B--;

Это не может быть последовательно решено, потому что вы присваиваете B значение 69 и , а затем после уменьшения B. Итак, что дает ответ: присваивание или пост-декремент?

С вашей платформой / IDE компилятор сделал что-то вроде этого, используя 'временную' переменную:

// Initial value of B is 69
temp = B--; // temp is 69 and B is now 68
B = temp;   // B now has the value of 69!

Однако вы не можете полагаться на эту «интерпретацию» - либо в разных компиляторах, либо даже используя похожий код в разных местах с одним и тем же компилятором!

PS: Кстати, вы должны публиковать код в виде текста, отформатированного каккод-блок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...