![]() |
|
Модераторы: bsa |
![]()
|
|
| Ground |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 321 Регистрация: 27.2.2006 Где: Комсомольск Репутация: нет Всего: 1 |
Вообщем проблемка у меня следующего характера. Есть код:
Если я считаю вручную это выражение, то получается (0100 | 1000) & (10100) = 01100 & 10100 = 100 = 4. Если проверяю все это выражение в C++ получается 3. Если по частям, то левая часть равна 12, правая 20, 12 & 20 = 4. В чем тут загвоздка? |
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 2 Всего: 37 |
a-- уменьшит a на 1 но значение этого выражения - a до изменения. Т.е 5. Да и в правой части логического умножения a уже изменено
Это сообщение отредактировал(а) Sartorius - 19.2.2009, 17:23 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 27 Всего: 154 |
это undefined behavior
|
|||
|
||||
| Kurganec |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 6.6.2008 Где: СПБ Репутация: нет Всего: нет |
мне кажется дело в постфиксе "--"
попробуй так:
|
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
Kurganec, Lazin дал вполне однозначный ответ
|
|||
|
||||
| cutwater |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 592 Регистрация: 24.6.2008 Репутация: 2 Всего: 10 |
Извините за глупый вопрос. Почему именно undefined behaviour?
|
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 4 Всего: 39 |
лучше так
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| mes |
|
||||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
попробуйте (мысленно) понаблюдать за поведением этого примера
при таком вступление
и таком :
во втором случае этот код альтернативен следующему
результат которого зависит от факторов трансляции выражения и по стандарту не определен. Это сообщение отредактировал(а) mes - 19.2.2009, 20:20 |
||||||||
|
|||||||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
если судить потому, чего хотел получить в результате тс:
то лучше так :
Это сообщение отредактировал(а) mes - 19.2.2009, 20:21 |
||||
|
|||||
| cutwater |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 592 Регистрация: 24.6.2008 Репутация: 2 Всего: 10 |
mes, благодарю за разъяснение.
|
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
дополню меса: тут два изменения одной переменной в одной точке следования, по стандарту это UB. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
что то изменение я нашел только одно... Это сообщение отредактировал(а) mes - 19.2.2009, 21:33 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
1. a = expression 2. a-- Добавлено через 3 минуты и 51 секунду это кстати не верно, последовательность вычислений тут вообще не причем, тут все проблемы с sequence points |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
т.е
уже не UB ?
a кто говорил о причинности в последовательности вычислений ? зависимость от последовательности приводилось лишь для более легкого понимания данной проблемы. да проблема с sequence points , но достаточно одного изменения и двойного использования этого значения в одной точке следования Это сообщение отредактировал(а) mes - 19.2.2009, 22:07 |
||||
|
|||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
vinter, давайте для начала проведем эксперемент.. у Вас VS ? что дает нижеприведенный код ?
|
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
ага то, что и должен 8 8 mes, нет тут UB. |
|||
|
||||
| Ground |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 321 Регистрация: 27.2.2006 Где: Комсомольск Репутация: нет Всего: 1 |
Всем спасибо за помощь!
|
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
т.е каждое слагаемое расценивалось как 4 ? не будем сейчас задаваться вопросом о правильности результата, просто немного усложним пример :
что теперь получается и как это объяснить ? Это сообщение отредактировал(а) mes - 20.2.2009, 13:21 |
||||
|
|||||
| zim22 |
|
|||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
можно сделать вывод, что в первую очередь вычисляются подвыражения, содержащие префиксную форму декремента. хотя я думал, что порядок вычисления подвыражений не определён... |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
приоритетом операций Добавлено через 53 секунды четко определен приоритетами. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
т.е у "* " и "/" разные приорететы по отношению к "--" ? |
|||
|
||||
| zim22 |
|
|||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
У меня в книжечке написано, что :
"За исключением логических операторов AND и OR, порядок вычисления парных операторов остается неопределенным, что обеспечивает компилятору свободу оптимизации кода."
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
о! хороший пример демонстрация гораздо нагляднее ) Это сообщение отредактировал(а) mes - 20.2.2009, 13:37 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
mes, вот чесное слово устал ты уже, открой таблицу приоритетов.. префиксный -- приоритетней всех арифметических операций. Мне больше тут нечего сказать.
это unspecified behavior, чувствуешь разницу с undefined? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
..
Это сообщение отредактировал(а) mes - 20.2.2009, 17:51 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
mes, значит в gcc баг, VS выдает все как должно быть
Добавлено через 1 минуту и 5 секунд а попробуй так
это абсолютный эквивалент твоей записи |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну вот последний пример :
интересно как в данном примере сказывается приоритет опeраций на разном результате ? Добавлено через 3 минуты и 24 секунды результат как и прежде Добавлено через 11 минут и 56 секунд не очень.. |
||||
|
|||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
||||
|
||||
| nickless |
|
|||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
ИМХО это - UB, а1 читается 2 раза и изменяется 1 раз между точками следования, результат зависит от того, когда запишется изменение. А gcc с -Wall кстати ворнинг выдаёт:
-------------------- ![]() 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 |
nickless, тут одна точка, разберем выражение:
int b= (--a1) + (a1*2); т.к мы имеем два подвыражения, которые имеют одинаковый приоритет срабатывает lef-to-right-order. Следовательно первым отрабатывай декремент, затем умножение и только потом сложение. Тту не надо программирование знать это элементарная математика, т.е мы имеем два слагаемых, вычисление которых более приоритетно чем само сложение. Следовательно я не вижу даже unspecified, не то что undefined.. GCC смущает, не верю в тупость такого хорошего компилятора.. В результате есть небольшой ступор, но судя здравой логике - в gcc баг. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| nickless |
|
||||||||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
Точка то одна, но даже если взять часть выражения:
тут между двумя точками мы 2 раза читаем и декрементируем а1. Я думаю тут вот что действует:
Тут переполнение не ожидается, так что компилятор может и соптимизировать, кроме того:
Т.е. раз менять местами можно, а результат будет разный - получается UB. Кстати, на VS результат всегда тот же не зависимо от оптимизации итд.? Как насчет большего числа операндов? edit Чуть подлиньше пример
Это сообщение отредактировал(а) nickless - 20.2.2009, 22:24 -------------------- ![]() 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 |
а я знаю, они будут вычислены в пордяке приоритетов их операций! Мне честно надоело уже говорить в стену, вот вам 2 ссылки: http://www.do2.rksi.ru/library/courses/demo/tema1_3.dbk http://www.cyberguru.ru/programming/cpp/cp...up2-page39.html там расписаны приоритеты операций. Если есть, что возразить, то приводите факты большие чем вывод gcc. |
|||
|
||||
| zim22 |
|
|||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
VS 2008: 28 28 28 28 Это сообщение отредактировал(а) zim22 - 20.2.2009, 22:29 |
|||
|
||||
| vinter |
|
||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
nickless, ты не сказал ничего нового, точнее ты не совсем верно трактовал стандарт.
у нас не same result
вот оно, к чему относится Otherwise Добавлено через 2 минуты и 4 секунды 28 всюду, MSVC 9.0 full optimization |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну для начала воспользуемся одной из Ваших же ссылок(но заглянем на несколько страниц вперед) : http://www.cyberguru.ru/programming/cpp/cp...up2-page41.html
Это сообщение отредактировал(а) mes - 20.2.2009, 22:51 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
mes, ты вообще читаешь что пишут?
ХВАТИТ ПРИВОДИТЬ ПРИМЕРЫ ВЫРАЖЕНИЙ ГДЕ ПРИОРИТЕТ ОДИНАКОВ!!!(звиняюсь) В выражениях в этом топике приоритет не одинаков!!! Добавлено через 5 минут и 42 секунды давайте немного отвлечемся и представим, что мы в 3-ем класе, нам дают задание сказать результат выражения: 7*8 + 7*8. Сколько будет? как тут можно трактовать двояко? Добавлено через 10 минут и 3 секунды icc: все 28 |
|||
|
||||
| nickless |
|
||||||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
В таком случае такой код был бы вполне легитимен:
если бы это выполнялось в порядке приоритетов операций, было бы: преинкремент -> плюс -> постинкремент. Однако это известный вариант UB. Так как исключений из правил тут быть не должно, думаю что "i + ++i" тоже должен быть UB (хотя причина немного другая, i изменяется только один раз).
Точно такого примера пока не нашел, но есть такое выражение:
взято отсюда: http://gcc.gnu.org/bugs.html#nonbugs_c Добавлено через 1 минуту и 4 секунды ЗЫ Последний пример - UB Добавлено через 3 минуты и 29 секунд Кстати баг это или нет, но такой код компиляторозависим и лучше так не делать -------------------- ![]() 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 |
полная чушь, GCC идет лесом, у скобок приоритет выше чем у множения, а значит они выпеолняются первымси. Тут абсолютно предсказуемый результат. GCC - 1. нет, тут срабатывает правила о sequence point. 2 изменеyния в пределах одной точки - UB нет, сначала выполняется ++, потом + ### ошибок, лучше пойду спать Это сообщение отредактировал(а) vinter - 20.2.2009, 23:24 |
|||
|
||||
| nickless |
|
||||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
Зря ты так категорично, gcc тоже не дураки писали Поискал еще немного, похоже дело в этом: понять сложновато, но ИМХО это означает "доступ к предыдущему значению допустим лишь для вычисления значения, которое будет сохранено" Т.е. никакого чтения после того как значение было сохранено, даже теоретическая возможность этого есть UB. Сцылки: http://open-std.org/jtc1/sc22/wg14/www/docs/n1188.pdf Речь идёт о sequence points и "alowable orderings", вот этих: даётся пример что одна лишь возможность перестановки subexpressions таким образом, что переменная может быть изменена до чтения - это уже UB http://open-std.org/jtc1/sc22/wg14/www/docs/n1008.htm искать слово "prior" Предложение более внятного объяснения вышеприведённой цитаты стандарта, как пример UB даётся:
http://www.embedded.com/story/OEG20020625S0041 искать "prior" Объяснение этого самого "shall be accessed only to determine the value to be stored" Короче если ты всё еще считаешь что это не UB, давай ссылку на обсуждение стандарта или хотя-бы похожий пример для VS откуда-нибудь с MSDN. ЗЫ ИМХО стоит отделить обсуждение стандарта в общие вопросы -------------------- ![]() 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 |
http://msdn.microsoft.com/en-us/library/d45c7a5d(VS.71).aspx
http://msdn.microsoft.com/en-us/library/yck2zaey(VS.71).aspx Короче я нигде не нашел, почуму же дает UB, кроме gcc'шной багзиллы. Какие то туманные намеки на стандарт, ничего конкретного.
ну и? а у нас не так? для чего еще оно используется? это не undefined, а unspecified. А у нас в примере был префиксный оператор, о чем я в каждом посту напоминаю, а вы это просто игнорите...
а я это понимаю как "нельзя второй раз изменять" Подведу итог: В стандарте НЕТ четкого указания по порядку вычисления одинаковоприоритеных подвыражений, поэтому различные компиляторы творят, что хотят. Но зато есть приоритеты операций, которые, например gcc, игнорит. Что можно видеть на приммере: Этот пример полностью укладывается в порядок выполнения. Снчала вычисляется выражение в скобках, пооисходит сохранение нового значения i и только потом умножение. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
С порядком выполнения зависимых инструкций никто не спорит. Но вот чтение с памяти переменной i может быть произведено еще до выполнения операции инкремента. если подойти с другой стороны и раскрыть выражение то получится :
а порядок вычисления аргументов функции также неопределен. Это сообщение отредактировал(а) mes - 21.2.2009, 11:42 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
вот что будет |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
как бы то не было, gcc не нарушает стандарта, а вот писать код руководствуясь псевдоправильным поведением студии опасно. |
|||
|
||||
| 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. |