Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
 Аватар для ASCII
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 463

Order of evaluation

02.07.2016, 00:37. Показов 2924. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Никак не могу побороть 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)
-------------------------------------------------------------------------------------------
Побочный эффект (изменение левого аргумента) встроенного оператора присваивания и всех встроенных составных операторов присваивания расположены после вычисления значения (но не побочного эффекта) обоих аргументов (левого и правого) и расположены перед вычислением значения оператора присваивания (т.е. перед возвращением ссылки на измененный объект)


Но не нашел противоречий. Помогите понять это. Возможно на примере других выражений.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.07.2016, 00:37
Ответы с готовыми решениями:

Preprocessing evaluation order
Всем привет! Известно ли в каком порядке препроцессор обрабатывает файлы проекта? Из случая, который со мной сегодня приключился,...

Логические операции и правило Short Circuit Evaluation
Здравствуйте. Прошу помощи, так как мнения по данным вопросам расходятся 1.Какое значение будет принимать х ? #include int...

HSQL запрос. Что не так? "from hiberdata.Order order where order.clientId=?"
public List loadOrdersByClientId(Integer clientId) { return getHibernateTemplate().find( 'from hiberdata.Order order where...

35
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
02.07.2016, 16:40
Лучший ответ Сообщение было отмечено ASCII как решение

Решение

Студворк — интернет-сервис помощи студентам
Цитата Сообщение от ASCII Посмотреть сообщение
А вот там где комментарий вставил, туда компилятор может поместить еще какие-то инструкции по вычислению какой-то другой части выражения?
Вполне. В пределах "точки следования"
компилятор творить выполнять всякое разное, что,
по его компетентному мнению, не приведет к изменению результата
Правда, он еще вполне может выражения между собой местами менять,
что может напакостить сильно, но это уже другая тема

Добавлено через 1 минуту
Цитата Сообщение от ASCII Посмотреть сообщение
Безвредно, в смысле само по себе это не UB
Да, это нормальное выражение.
Цитата Сообщение от ASCII Посмотреть сообщение
когда мы это присваиваем объекту i?
Да, потому что не ясно становится что в каком порядке будет вычислено.
поэтому еще раз:
Цитата Сообщение от Croessmah Посмотреть сообщение
не нужно менять значение одного объекта несколько раз в одном выражении (expression, full-expression),
если нет явно выраженного порядка выполнения.
В i = i++ + 1, вы i меняете дважды, причем порядок изменений не определен.
0
 Аватар для ASCII
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 463
02.07.2016, 16:41  [ТС]
Цитата Сообщение от 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/c... eval_order
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
02.07.2016, 16:41
Цитата Сообщение от ASCII Посмотреть сообщение
secuence point rule вроде бы в С++11 уже нету? Его заменили на sequence before rule...
Милицию в полицию тоже переименовали
Думаю, смысл высказывания ясен
1
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
02.07.2016, 16:42
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.
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
02.07.2016, 16:52
Цитата Сообщение от ct0r Посмотреть сообщение
забей на компилятор
и на всё остальное тоже?
0
 Аватар для ASCII
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 463
02.07.2016, 17:00  [ТС]
Цитата Сообщение от 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
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
02.07.2016, 17:02
Цитата Сообщение от ASCII Посмотреть сообщение
ОПЕРАНДЫ ВЫЧИСЛИЛИ.
Одна поправочка.
Для вычисления значений i++ + 1 достаточно копии i.
Фактически, именно она и будет операндом,
а когда будет вычислено остальное - уже пофигу,
значение i++ + 1 от этого не изменится.
1
 Аватар для ASCII
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 463
02.07.2016, 17:03  [ТС]
ct0r, ну не компилятор, так абстрактная машина, которая должна обеспечить наблюдаемый результат в соответствии с некими правилами. И вот как раз, почему эта машина делает именно так, а не иначе, я и хочу понять)
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
02.07.2016, 17:06
Croessmah, как вариант. Зачем нужно писать всякие ++ в выражениях, если это можно просто написать отдельно, что читабельнее и менее подвержено ошибкам? Разве что чужой быдлокод читать?
0
 Аватар для ASCII
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 463
02.07.2016, 17:06  [ТС]
Croessmah, про копию помню, я ее тут сознательно не упомянул, ибо
Цитата Сообщение от Croessmah Посмотреть сообщение
значение i++ + 1 от этого не изменится.
Что кстати и путает. Ведь если значение выражения не меняется, а порядок для оператора = задан.
То чем это отличается от, например

C++
1
i = 2;
Ведь все равно значение i затрется результатом выражения.
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
02.07.2016, 17:09
Цитата Сообщение от ct0r Посмотреть сообщение
Зачем нужно писать всякие ++ в выражениях, если это можно просто написать отдельно, что читабельнее и менее подвержено ошибкам?
Вы меня спрашиваете?
Я стараюсь даже типы в литералах указывать
C++
1
float f = 3.0f;//а не 3.0
Цитата Сообщение от ct0r Посмотреть сообщение
Разве что чужой быдлокод читать?
Часто делают просто для того, чтобы строчки экономить. А надо ли оно?

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

Добавлено через 1 минуту
Croessmah, а Вы чего не онлайн? Точно как бот
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
02.07.2016, 17:15
Цитата Сообщение от ASCII Посмотреть сообщение
а Вы чего не онлайн? Точно как бот
Ну, ежели я бот, то мне можно
1
 Аватар для ASCII
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 463
02.07.2016, 17:16  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
Ну, ежели я бот, то мне можно
Я просто вспомнил одну тему, в которой Вас ботом назвали
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
02.07.2016, 17:18
Цитата Сообщение от ASCII Посмотреть сообщение
в которой Вас ботом назвали
И сделал это ct0r.
Совпадение? Не думаю.
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
02.07.2016, 17:29
Лучший ответ Сообщение было отмечено ASCII как решение

Решение

Цитата Сообщение от Croessmah Посмотреть сообщение
Вы меня спрашиваете?
Вдруг знаешь сокровенный смысл

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

Цитата Сообщение от Croessmah Посмотреть сообщение
И сделал это ct0r.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.07.2016, 17:29
Помогаю со студенческими работами здесь

Function evaluation timed out
IEnumerable<Market> allMarkets = getAllMarkets();//count ~= 450 IEnumerable<int> neededIds = new int {164633}; IEnumerable<Market>...

Order by внутри order by
Добрый день, есть условно таблица с пользователями, у которых есть несколько сообщений, хранящихся в другой таблице user: id...

STM32 comStick Evaluation Board
Так и быть, расскажу, чего сейчас ковыряю :) Был на последней выставке в Нюрнберге Embeddid World. Там по работе подходил к стенду ST...

CodeVisionAVR Evaluation V2.05.3a выдает ошибку
При построении hex-файла выдает ошибку "Error(s) occured during assembly" Подскажите начинающему!!! Заранее благодарен.

Чем отличается Windows 8.1 Enterprise Evaluation?
На официальном сайте Microsoft technet.com нельзя скачать обычную Windows 8.1 Enterprise, а только Windows 8.1 Enterprise Evaluation....


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

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru