Форум программистов, компьютерный форум CyberForum.ru

Order of evaluation - C++

Восстановить пароль Регистрация
 
 
ASCII
 Аватар для ASCII
82 / 54 / 8
Регистрация: 15.12.2013
Сообщений: 369
Завершенные тесты: 2
02.07.2016, 00:37     Order of evaluation #1
Всем привет. Никак не могу побороть Order of evaluation. В статье на cppreference, приводятся примеры UB и уже на первом я застреваю и не понимаю почему именно так:

If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.
Если побочный эффект для скалярного объекта не упорядочен по отношению к другому побочному эффекту для этого же объекта - поведение не определено

C++
1
i = ++i + i++; // undefined behavior
Собственно тут я не знаю как мыслить. Как подобного рода UB находить в программах? Я пытался применять правила, которые описаны в Secuenced before rule, но ими я не смог объяснить UB приведенного выше примера.

Собственно для примера выше пытался применить правила:

2) The value computations (but not the side-effects) of the operands to any operator are sequenced before the value computation of the result of the operator (but not its side-effects).
-------------------------------------------------------------------------------------------
Вычисление значений (но не побочных эффектов) операндов любого оператора расположены перед вычислением значения оператора в целом (но не его побочного эффекта)

8) The side effect (modification of the left argument) of the built-in assignment operator and of all built-in compound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object)
-------------------------------------------------------------------------------------------
Побочный эффект (изменение левого аргумента) встроенного оператора присваивания и всех встроенных составных операторов присваивания расположены после вычисления значения (но не побочного эффекта) обоих аргументов (левого и правого) и расположены перед вычислением значения оператора присваивания (т.е. перед возвращением ссылки на измененный объект)


Но не нашел противоречий. Помогите понять это. Возможно на примере других выражений.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.07.2016, 00:37     Order of evaluation
Посмотрите здесь:

C++ Описать структуру с именем Order
Описание структуры ORDER C++
Использование класса ORDER C++
Пояснение структуры ORDER C++
C++ Описать структуру с именем Order
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
02.07.2016, 16:40     Order of evaluation #21
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от ASCII Посмотреть сообщение
А вот там где комментарий вставил, туда компилятор может поместить еще какие-то инструкции по вычислению какой-то другой части выражения?
Вполне. В пределах "точки следования"
компилятор творить выполнять всякое разное, что,
по его компетентному мнению, не приведет к изменению результата
Правда, он еще вполне может выражения между собой местами менять,
что может напакостить сильно, но это уже другая тема

Добавлено через 1 минуту
Цитата Сообщение от ASCII Посмотреть сообщение
Безвредно, в смысле само по себе это не UB
Да, это нормальное выражение.
Цитата Сообщение от ASCII Посмотреть сообщение
когда мы это присваиваем объекту i?
Да, потому что не ясно становится что в каком порядке будет вычислено.
поэтому еще раз:
Цитата Сообщение от Croessmah Посмотреть сообщение
не нужно менять значение одного объекта несколько раз в одном выражении (expression, full-expression),
если нет явно выраженного порядка выполнения.
В i = i++ + 1, вы i меняете дважды, причем порядок изменений не определен.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ASCII
 Аватар для ASCII
82 / 54 / 8
Регистрация: 15.12.2013
Сообщений: 369
Завершенные тесты: 2
02.07.2016, 16:41  [ТС]     Order of evaluation #22
Цитата Сообщение от Croessmah Посмотреть сообщение
В пределах "точки следования"
secuence point rule вроде бы в С++11 уже нету? Его заменили на sequence before rule...
В следствии чего:

C++
1
i = ++i + 1; // undefined behavior (well-defined in C++11)
До С++11 было UB
http://en.cppreference.com/w/cpp/language/eval_order
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
02.07.2016, 16:41     Order of evaluation #23
Цитата Сообщение от ASCII Посмотреть сообщение
secuence point rule вроде бы в С++11 уже нету? Его заменили на sequence before rule...
Милицию в полицию тоже переименовали
Думаю, смысл высказывания ясен
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
02.07.2016, 16:42     Order of evaluation #24
ASCII, забей на компилятор. У него вообще большая свобода действий (в разумных пределах конечно). В стандарте речь не о нем:
The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
02.07.2016, 16:52     Order of evaluation #25
Цитата Сообщение от ct0r Посмотреть сообщение
забей на компилятор
и на всё остальное тоже?
ASCII
 Аватар для ASCII
82 / 54 / 8
Регистрация: 15.12.2013
Сообщений: 369
Завершенные тесты: 2
02.07.2016, 17:00  [ТС]     Order of evaluation #26
Цитата Сообщение от Croessmah Посмотреть сообщение
Да, потому что не ясно становится что в каком порядке будет вычислено.
Цитата Сообщение от Croessmah Посмотреть сообщение
В i = i++ + 1, вы i меняете дважды, причем порядок изменений не определен.
Вот тут мы в плотную подошли к моменту, который меня на самом деле до сих пор путает.
Смотрите, имеем общее правило для вычисления операндов какого-либо оператора:

2) The value computations (but not the side-effects) of the operands to any operator are sequenced before the value computation of the result of the operator (but not its side-effects).

То есть просто сказано, что сначала вычисляются операнды, а только потом результат всего оператора. Все.
Далее у нас есть также и частный случай для операторов присвоения.

8) The side effect (modification of the left argument) of the built-in assignment operator and of all built-in compound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object)

Тут уже говорится несколько иначе. Первым делом вычисляются значения операндов оператора присваивания, то есть объект, которому присваивается и "результирующий объект", полученный после вычисления выражения, которое присваивается.

C++
1
a = B; /* где B - любое выражение, не обязательно идентификатор переменной */
Затем, только после вычисления значений этих операндов, происходит side effect левого аргумента.
И УЖЕ ПОСЛЕ ЭТОГО, происходит финальный value computation.

То есть тут получается все упорядочено оказывается? И это сбивает с толку. Ведь если следовать этим правилам (а другие правила тут не работают вроде-бы), то по моим умозаключениям получаем такую картину:

C++
1
2
int i = 0;
i = i++ + 1;
1 Этап - вычисляем операнды.
Поехали:

Первый вариант - сначала i, потом i++ + 1
i == 0 - вычислили, i - просто идентификатор, стоящий слева, не содержит никаких подвыражений.
i++ + 1 - опять, можем считать сначала i++, потом 1, или наоборот, но в данном случае, это не важно.
i++ == 0, i становится равной 1
получаем - 1 + 1.

Второй вариант - сначала i++ + 1, потом i
получим в итоге для i++ + 1 - 1 + 1
но на стадии вычисления i получим 1, но какая разница? Если это затирается?
Ничего не поменяется ведь...
Где-то тут чувствую я ошибаюсь

ОПЕРАНДЫ ВЫЧИСЛИЛИ.


2 Этап - side effect для левого операнда
Тут ясно все, все по порядку, вычислили операнды, и начинаем изменять объект i, присваиваем результат 1 + 1

Ну и финал - возврат ссылки на i, как результата выражения.

Вот и получается, что тут будет 2

Добавлено через 2 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
Милицию в полицию тоже переименовали
Думаю, смысл высказывания ясен
Смысл то ясен
На самом деле я хотел сказать о другом, что некоторые операции, которые в соответствии с правилом sequence point были UB, могут не являться таковыми в соответствии с правилом sequence before
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
02.07.2016, 17:02     Order of evaluation #27
Цитата Сообщение от ASCII Посмотреть сообщение
ОПЕРАНДЫ ВЫЧИСЛИЛИ.
Одна поправочка.
Для вычисления значений i++ + 1 достаточно копии i.
Фактически, именно она и будет операндом,
а когда будет вычислено остальное - уже пофигу,
значение i++ + 1 от этого не изменится.
ASCII
 Аватар для ASCII
82 / 54 / 8
Регистрация: 15.12.2013
Сообщений: 369
Завершенные тесты: 2
02.07.2016, 17:03  [ТС]     Order of evaluation #28
ct0r, ну не компилятор, так абстрактная машина, которая должна обеспечить наблюдаемый результат в соответствии с некими правилами. И вот как раз, почему эта машина делает именно так, а не иначе, я и хочу понять)
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
02.07.2016, 17:06     Order of evaluation #29
Croessmah, как вариант. Зачем нужно писать всякие ++ в выражениях, если это можно просто написать отдельно, что читабельнее и менее подвержено ошибкам? Разве что чужой быдлокод читать?
ASCII
 Аватар для ASCII
82 / 54 / 8
Регистрация: 15.12.2013
Сообщений: 369
Завершенные тесты: 2
02.07.2016, 17:06  [ТС]     Order of evaluation #30
Croessmah, про копию помню, я ее тут сознательно не упомянул, ибо
Цитата Сообщение от Croessmah Посмотреть сообщение
значение i++ + 1 от этого не изменится.
Что кстати и путает. Ведь если значение выражения не меняется, а порядок для оператора = задан.
То чем это отличается от, например

C++
1
i = 2;
Ведь все равно значение i затрется результатом выражения.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
02.07.2016, 17:09     Order of evaluation #31
Цитата Сообщение от ct0r Посмотреть сообщение
Зачем нужно писать всякие ++ в выражениях, если это можно просто написать отдельно, что читабельнее и менее подвержено ошибкам?
Вы меня спрашиваете?
Я стараюсь даже типы в литералах указывать
C++
1
float f = 3.0f;//а не 3.0
Цитата Сообщение от ct0r Посмотреть сообщение
Разве что чужой быдлокод читать?
Часто делают просто для того, чтобы строчки экономить. А надо ли оно?

P.S. форум - отдельная эпопея, без строгих правил
ASCII
 Аватар для ASCII
82 / 54 / 8
Регистрация: 15.12.2013
Сообщений: 369
Завершенные тесты: 2
02.07.2016, 17:11  [ТС]     Order of evaluation #32
Цитата Сообщение от ct0r Посмотреть сообщение
Зачем нужно писать всякие ++ в выражениях, если это можно просто написать отдельно, что читабельнее и менее подвержено ошибкам?
Это конечно логично, но это с практической точки зрения. Я лишь преследую "понимание"
Дело в том, что читая Энтони Вильямса (я несколько книг читаю по многопоточности параллельно, кстати одну из которых мне советовали Вы и Убежденный), он начал объяснять про memory_order, то бишь про порядок доступа к памяти. А объясняя это, он вводит понятие "синхронизируется-с", которое базируется на правиле "расположено-перед", и вот из-за непонимания его, я не могу продолжить чтение

Добавлено через 1 минуту
Croessmah, а Вы чего не онлайн? Точно как бот
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
02.07.2016, 17:15     Order of evaluation #33
Цитата Сообщение от ASCII Посмотреть сообщение
а Вы чего не онлайн? Точно как бот
Ну, ежели я бот, то мне можно
ASCII
 Аватар для ASCII
82 / 54 / 8
Регистрация: 15.12.2013
Сообщений: 369
Завершенные тесты: 2
02.07.2016, 17:16  [ТС]     Order of evaluation #34
Цитата Сообщение от Croessmah Посмотреть сообщение
Ну, ежели я бот, то мне можно
Я просто вспомнил одну тему, в которой Вас ботом назвали
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
02.07.2016, 17:18     Order of evaluation #35
Цитата Сообщение от ASCII Посмотреть сообщение
в которой Вас ботом назвали
И сделал это ct0r.
Совпадение? Не думаю.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2016, 17:29     Order of evaluation
Еще ссылки по теме:

Создать класс Order C++
C++ Preprocessing evaluation order

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
02.07.2016, 17:29     Order of evaluation #36
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Croessmah Посмотреть сообщение
Вы меня спрашиваете?
Вдруг знаешь сокровенный смысл

Цитата Сообщение от ASCII Посмотреть сообщение
А объясняя это, он вводит понятие "синхронизируется-с", которое базируется на правиле "расположено-перед", и вот из-за непонимания его, я не могу продолжить чтение
На русском конкретно эту тему жесть читать, я сам, когда первый раз читал, не понял вообще ничего Пришлось брать англ вариант и поднимать дополнительные статьи. Вот например пара:
http://preshing.com/20130702/the-hap...fore-relation/
http://preshing.com/20130823/the-syn...with-relation/

Цитата Сообщение от Croessmah Посмотреть сообщение
И сделал это ct0r.
Yandex
Объявления
02.07.2016, 17:29     Order of evaluation
Ответ Создать тему
Опции темы

Текущее время: 05:15. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru