| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > не понимаю компилятор |
| Автор: 17dufa 30.10.2009, 11:47 | ||
| Добрый день. Есть красивая подстава на собеседовании: int i = 0; i = i++; чему равно i? однако, компилятор мелкософта, а по сведениям и какие-то из линуксовых выдают i == 1. вот собственно код
при выходе из main jk = 1, а вот i.val = 0 - как и ожидалось. откуда такая разница для встроенного и пользовательского типа? |
| Автор: Alek86 30.10.2009, 12:04 |
| оттуда, что поведение не определено (или не специфицированно, не помню точно) если ты напишешь код, у которого undefined behaviour, компилятор имеет моральное право хоть код для BSOD'а вставлять |
| Автор: mes 30.10.2009, 12:22 | ||||
для удобства в выражении i = i++; заменим i ссылками на нее же :
теперь разобьем по действиям : (условно a и b регистры процессора)
результат зависит от того, какая из закомментированных строк будет использована.. точнее от порядка следования инструкций сохранения значения. как тут поступить решает компилятор, так как в стандарте нет жестких указаний на данный случай. |
| Автор: 17dufa 30.10.2009, 12:57 | ||
| Alek86, что конкретно в этом коде выводит нас в чудную область undefined behaviour? mes, думаю Вы несколько ошиблись в коде (перепутали a и b в последней части)
а разве не определено стандартом, что сначала вычисляется правое выражение, а затем уже выполняется оператор равенства? это ж форменный бардак получается, если side эффекты правого выражения вычисляются после выполнения равенства. |
| Автор: tilin 30.10.2009, 13:30 | ||||
А почему i не должно быть равно 1? i хранится в памяти. i инкрементируется и сохраняется опять же туда. Соответственно при чтении i читается из памяти и читается именно 1. Асм код от мелкософта:
|
| Автор: mes 30.10.2009, 13:32 |
потому что может быть и другая реализация.. Не мелкософтом единным жив программист |
| Автор: tilin 30.10.2009, 13:35 |
| А при другой реализации i будет храниться в двух разных местах что-ли? Ведь, если хранится в одном месте памяти, то i++ изменяет значение именно этой ячейки и соответственно i == 1 при любом порядке выполнения. |
| Автор: 17dufa 30.10.2009, 13:40 |
| tilin, ну вот Вы и попались i=i++ - это единая конструкция. и в оператор = передается значение i до инкрементирования, то есть 0. потом происходит инкремент, i становится 1, потом собственно выполняется оператор = и i снова становится 0;) а приведенный Вами код несколько отличается от того, что я написал в самом начале. так что в идеале i = 0. что и происходит с моим типом ii. там компилятор себе такого не позволяет. mes, ну все, если терь меня такое спросят так и буду грить - undefined behaviour и Вашу красивую схему с регистрами tilin, исправились, так что и я исправлюсь - постфиксный инкремент создает копию объекта, глубоко по идее. так что да, в 2 местах будет хранится. обратите внимание на реализацию operator++(int) в первом посте темы. |
| Автор: mes 30.10.2009, 13:45 | ||||
если http://forum.vingrad.ru/index.php?showtopic=278366&view=findpost&p=2008829 остался без внимания, то повторю его изменив "Ваш" asm код :
Добавлено через 6 минут позвольте узнать, на что он может обидеться ?! |
| Автор: Earnest 30.10.2009, 13:55 | ||
Нет, компилятор имеет право делать присваивание и инкремент в любом порядке, т.к. инкремент постфиксный. Порядок вычисления независимых подвыражений в statement не определен. А результат i++ (т.е. старое значение i) может храниться во временной переменной. |
| Автор: 17dufa 30.10.2009, 14:04 |
| mes, если предположить, что он умный ровно настолько насколько я был до этого утра и твердо уверен что результат 0, то может обидеться, что я оказался умнее Earnest, вот где собака порылась. для моего типа это получается ни разу не независимое подвыраженее, и как следствие подобной вариативности нет, а постфиксный инкремент встроенного типа независимое подвыражение со всеми вытекающими. тогда все становится на свои места. |
| Автор: mes 30.10.2009, 14:06 | ||
или про точки следования, вот с википедии : http://en.wikipedia.org/wiki/Sequence_point
тогда зачем бы он стал бы задавать такой вопрос на собеседовании. ?! ну если уж работадатель задает вопросы, ответы на которые не знает, то ничего страшного если и покраснеет Все зависит от оптимизационных способностей компилятора.. |
| Автор: 17dufa 30.10.2009, 14:16 |
| mes, познавательно. и что самое интересное "i=i++;" даже обсуждается отдельно. |