![]() |
|
Модераторы: bsa |
![]()
|
|
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
спорный вопрс я четкого регламента так и не нашел. Так, что видимо стандарт сам темнит в этой ситуации. |
|||
|
||||
| nickless |
|
||||||||||||||||||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
Хм, в MSDN тоже никакой конкретики, только на счет side effects есть:
http://msdn.microsoft.com/es-es/library/8a425116.aspx
В примере постинкремент, но преинкремент тоже имеет side effect, так что он ИМХО ничем не лучше. Почему unspecified когда там четко написано undefined?
А чем он отличается от постфиксного? Ведь по стандарту разница лишь в возвращаемом значении ++i vs. i++, а момент, когда результат инкремента будет записан в переменную определён лишь точками следования, которая в примере
одна в конце выражения. Про второй раз изменять там написано отдельно:
это условие выполняется, а вот это:
нет. Ты pdf читал? Там как раз про это. Приоритеты операций в данном случае не имеют значения, как и в a[i] = i++; Порядок выполнения тут не нарушается, проблема в том, что выражение ++i имеет побочный эффект. По стандарту, результат побочного эффекта достигнет переменной к следующей точке следования, а не до оператора умножения. Получается два возможных варианта: [точка следования n] читаем i, инкрементируем, сохраняем новое значение, читаем i, складываем, [точка следования n+1] [точка следования n] читаем i, инкрементируем, читаем i, складываем, сохраняем новое значение, [точка следования n+1] Оба варианта следуют стандарту, а результат разный - слöедовательно это UB.
Нет, порядок выполнения не влияет на сохранение нового значения. Если бы это было что-то вроде
то да, новое значение i было бы сохранено до присваивания, т.к. && определяет точку следования, а + или * точки следования не определяют.
+1
Это пример только для C++, в случае с C причина немного другая. -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
||||||||||||||||||
|
|||||||||||||||||||
| vinter |
|
||||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
там есть гарантия порядка выполнения, например что при < вычислен сначала будет левый аргумент. у префиксного наивысший приоритет, у постфиксного наинизший.
блин, а по твоему когда мы пишем просто x* мы как то вступаем в противоречие с этой фразой?
как это? т.е ты хочешь сказать, что изменения в переменных происходят только по завершении точки следования? Это 100% чушь, т.к в этом случае ни одно выражение не может быть построено. Пример с твоих слов: x = y * ++z; UB, т.к z изменится ятолько по завершению эволюции выражения. |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
да z в памяти изменится только по завершению эволюции, но это не UB так как никто не использует эту память. а то что предназначено для умножения как правый множитель (но это не z!) будет иметь значение инкрементированого z. P.S. мне кажется Вы упустили, что арифметические операции проходят не с ячейками памяти, а с регистрами в которые вначале загружаются значения и из которых в дальнейшем результат записывается в память. т.е значения которое отдала переменная для расчетов и которое в действительности хранится в ее памяти в определенные моменты времени отличаются.. Это сообщение отредактировал(а) mes - 21.2.2009, 19:03 |
|||
|
||||
| nickless |
|
||||||||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
Нет конечно
Нравится тебе это или нет, но в стандарте так и написано:
Да, z изменится только после завершения эвалюации, но это не UB, т.к. z больше не используется, а результат выражения ++z чётко определён. Добавлено через 1 минуту и 32 секунды ЗЫ Медленно я пишу... -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
||||||||
|
|||||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
ок. Стандарт все таки более дебилен, чем я думал. Спасибо за дискуссию. |
|||
|
||||
| Ground |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 321 Регистрация: 27.2.2006 Где: Комсомольск Репутация: нет Всего: 1 |
Две ссылки приведенные выше дают разную информацию:
http://www.do2.rksi.ru/library/courses/demo/tema1_3.dbk http://www.cyberguru.ru/programming/cpp/cp...up2-page39.html Первая говорит, что у постфиксного инкремента и декремента самый низний приоритет из операций, а префиксного самый высокий. Вторая ссылка утверждает что у них одинаковый приоритет. Кому верить? И в какой все-таки последовательности нужно считать a=(a--|x<<2)&(a<<2), чтобы получить 3, как и выдает си? Получается выполнять сначало все действия в скобках, за исключением декремента, и потом от финального значения отнимать единицу? Это сообщение отредактировал(а) Ground - 23.2.2009, 08:48 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
тут стопроцентный Undefined behavior лучше все таки верить Страуструпу. Но там не совсем верная таблица приведена. Сейчас открыл книгу приоритет постфиксных операций, выше чем префиксных.. |
|||
|
||||
| Ground |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 321 Регистрация: 27.2.2006 Где: Комсомольск Репутация: нет Всего: 1 |
Я просто пытаюсь понять алгоритм си.
Все дело в том, что в дальнейших вычислениях у меня есть квадратный корень, и при ответе a=4 (если считать выражение UB, и исправить это), у меня получается отрицательное значение под ним, а при a=3 (исходное выражение, без исправлений) все сходится. Т.е. программа считает как мне необходимо дальше по заданию. Возможно это ошибка в задании. Если читать первую ссылку, то получается что у постфиксного декремента самый низкий приоритет, и тогда мы вычисляем (a|x<<2)&(a<<2), а потом находим декремент этого выражения, то у меня получится 3, как и у программы. В резуальтате выходит, что дело в приоритете операций. Это сообщение отредактировал(а) Ground - 23.2.2009, 10:20 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
Ground, не читай первую ссылку
|
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |