пример - стандарт c++ 17




Итак, почему i=++ i+1 четко определен в C++ 11? (2)

... или вычисление значения с использованием значения одного и того же скалярного объекта ...

Здесь важна важная часть. Левая сторона не использует значение i для вычисления значения. То, что вычисляется, является значением glvalue . Только после этого (после последовательности) значение объекта коснется и заменяется.

К сожалению, это очень тонкая точка :)

Я видел other подобные questions и читал об этом defect . Но я все еще не понимаю. Почему i = ++i + 1 хорошо определен в C ++ 11, когда i = i++ + 1 нет? Как стандарт четко определяет это?

По моей разработке, у меня есть следующий секвенсор перед графиком (где стрелка представляет собой упорядоченную до отношения, и все это вычисление значения, если не указано иное):

i = ++i + 1
     ^
     |
assignment (side effect on i)
 ^      ^
 |      |
☆i   ++i + 1
     ||    ^
    i+=1   |
     ^     1
     |
★assignment (side effect on i)
  ^      ^
  |      |
  i      1

Я отметил побочный эффект на i с черной звездой и вычислением значения i с белой звездой. Они кажутся непоследовательными по отношению друг к другу (согласно моей логике). И стандарт говорит:

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

Объяснение в defect о defect не помогло мне понять. С чем связано преобразование lvalue-to-rvalue? Что я сделал неправильно?


Ну, ключевой момент здесь заключается в том, что результат ++i является lvalue . И для того, чтобы участвовать в бинарном + , значение lvalue должно быть преобразовано в rvalue путем преобразования lvalue-to-rvalue. Преобразование Lvalue-to-rvalue - это в основном акт чтения переменной i из памяти.

Это означает, что значение ++i должно быть получено, как если бы оно было прочитано непосредственно из i . Это означает, что концептуально новое (увеличенное) значение i должно быть готово (должно быть физически сохранено в i ) до того, как начнется оценка двоичного файла + .

Это дополнительное упорядочение - это то, что непреднамеренно создало поведение, определенное в этом случае.

В C ++ 03 не было строгого требования получить значение ++i непосредственно из i . Новое значение могло быть предсказано / предустановлено как i + 1 и использовано как операнд двоичного кода + даже до того, как оно было физически сохранено в фактическом i . Хотя можно утверждать, что требование было неявно там даже в C ++ 03 (и тот факт, что C ++ 03 не признал его существование, был дефектом C ++ 03)

В случае i++ результатом является rvalue . Поскольку это уже значение rvalue, нет никакого преобразования lvalue-to-rvalue, и нет абсолютно никакого требования хранить его в i прежде чем мы начнем оценивать двоичный файл + .





language-lawyer