| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Почему такой результат??? |
| Автор: it_medved 10.5.2007, 14:30 | ||
Не могу врубится, почему данное выражение приводит к результату 14...
|
| Автор: Fazil6 10.5.2007, 14:50 |
| а какому результату оно должно приводить? Все правильно. 2 раза проинкрементировал. 7 + 7 = 14. |
| Автор: Anikmar 10.5.2007, 14:51 |
| Думаю с точки зрения раскрутки и очередности операций все правильно: 1-е действие: инкремент i. Результат помещается в i (6) 2-е действие: инкремент i. Результат помещается в i (7) 3-е действие Берется значение i (7) И прибавляется к значению i(7) - результат 14. А вот с точки зрения здравого смысла - судить не берусь. |
| Автор: Daevaorn 10.5.2007, 15:00 |
| Это UB. Результат может быть любым |
| Автор: Anikmar 10.5.2007, 15:03 |
А что такое UB? Результат не может быть любым. Он может быть либо 12 либо 13 либо 14 С точки зрения здравого смысло (имхо) ожидается 13 |
| Автор: nerezus 10.5.2007, 15:11 | ||
|
| Автор: Xenon 10.5.2007, 15:23 |
| Это стопудовый UB. Даже у Страуструпа четко прописано. |
| Автор: Anikmar 10.5.2007, 15:29 | ||
Разве может быть абсолютно любое? Я считал, что только в рамках последовательности операций. И у Страуструпа по-моему именно так и описывается: последовательность зависит от реализации. Но меньше 11 результат быть не может, так же как и больше 14. |
| Автор: zkv 10.5.2007, 15:38 | ||
да какая разница, абсолютно любое или какое то из определенного множества, в любом случае использовать такой код нельзя. |
| Автор: Daevaorn 10.5.2007, 15:44 |
если это UB, то может быть всё что угодно. Любые варианты - это гадание на кофейной гуще. |
| Автор: Anikmar 10.5.2007, 15:58 | ||||
Налетели! Согласен я, естественно, просто из врожденной вредности: не любое, а из перечня (псевдо) неправильных результатов - вот я и занудствую. Проехали. Вывод: Так делать нельзя. (Таракан без ног не слышит!) |
| Автор: nickless 10.5.2007, 16:04 |
| http://www.research.att.com/~bs/bs_faq2.html#evaluation-order Даже пример тот же |
| Автор: it_medved 10.5.2007, 18:22 |
| Фу, зардражают такие вопросики, неужели такая белиберда важна при реализации настоящей программы??? |
| Автор: nickless 10.5.2007, 18:41 | ||
Ну почему белиберда? Не будешь знать об этом, обязательно где-нибудь что-то подобное напишешь (для "оптимизации" например, или чтоб код короче был), и будет такая программа потом работать только по полнолуниям |
| Автор: it_medved 10.5.2007, 18:56 |
| Да ну его, я таким бредом заниматся не буду И все же вернемся к вопросу. Я тут покумекал, и выходит, так ++i; // i==6 ++i;// i==7 i+i// i==13... но с компилятором не поспоришь... это наверное как необьяснимое чудо |
| Автор: Hurricane 10.5.2007, 19:16 | ||
Как это у тебя 7+7=13 получается - не понимаю Ну решил компилятор делать сложение после второго инкремента - такая у него логика. На самом деле - важно понимать, что это UB и избегать таких неоднозначностей, а не пытаться объяснить, почему данная реализация компилятора делает так, а не иначе в этом случае. |
| Автор: it_medved 10.5.2007, 19:26 |
| не гони! Читай внимательно!!! Добавлено через 1 минуту и 8 секунд Так это все зависит от компилятора??? Добавлено через 1 минуту и 50 секунд UB - Universal Baran? |
| Автор: nickless 10.5.2007, 19:54 |
ага Undefined Behavior |
| Автор: dizzy1984 10.5.2007, 20:26 | ||||
Объяснение не сложное. Выражение ++i + ++i. Нарушает правило которое гласит, что нельзя модифицировать переменную зажатую между 2-мя точками следования более 1-го раза. Это ведет к UB. Здесь я так понимаю 1-я точка находится перед выражением, 2-я после. Если сильно приперло, то можно переписать это выражение с использованием функции.
Такой вариант всегда вернет ожидаемое. Т.к каждая ф-я обрамлена точками следования. Хотя порядок вычисления слагаемых все-равно не определен. |
| Автор: it_medved 10.5.2007, 20:28 |
| Раз все пришли к такомы выводу, то будет правильным сказать тем, кто дает такие вопросы на тестах на приеме на работу (не будем говорить кто |
| Автор: JackYF 10.5.2007, 20:44 |
Ну неопределенное поведение. То есть ни компилятор, ни стандарт не гарантируют тебе любого правила, по которому твое выражение будет вычислено. В общем, такого надо избегать. |
| Автор: it_medved 10.5.2007, 20:51 |
| А мне кажется, что состояние UB надо на уровне компиляции присваивать ошибку! |
| Автор: JackYF 10.5.2007, 20:56 | ||
а компилятор не факт, что сможет сам распознать UB. Хотя кто его знает... |
| Автор: turboNOMAD 10.5.2007, 20:57 |
| А можно ткнуть меня носом в компилеры, которые тут выдают че-то другое, кроме 14? Самому лень искать |
| Автор: nickless 10.5.2007, 21:09 | ||
Было бы неплохо, но пожалуй сложно в реализации. Во всяком случае gcc выдаёт варнинг если компилировать с -Wall |
| Автор: it_medved 10.5.2007, 21:21 | ||
это как? |
| Автор: nickless 10.5.2007, 21:37 | ||
|
| Автор: dizzy1984 10.5.2007, 22:20 |
Запускаешь свою программу, она начинает форматировать твой жесткий диск |
| Автор: Rockie 10.5.2007, 23:07 |
| it_medved, "проверка на вшивость"? Эта тема уже поднималась, implementation-defined |
| Автор: nerezus 10.5.2007, 23:16 | ||
|
| Автор: turboNOMAD 11.5.2007, 15:09 | ||
C# тоже, как известно, выдает 13. Я имел в виду сиплюсовые компиляторы ;) |
| Автор: JackYF 11.5.2007, 15:19 |
| quote=nickless, 10.5.2007, 21:37, post1129056]$ g++ -Wall -o bla bla.cpp bla.cpp: In function ‘int main()’: bla.cpp:18: warning: operation on ‘i’ may be undefined bla.cpp:18: warning: operation on ‘i’ may be undefined[/quote] Просто замечательно! Я сам не пробовал, но варнинг - это уже хорошо. По крайней мере, есть предупреждение. |
| Автор: smartov 11.5.2007, 18:06 |
| nerezus, у меня перл выдал 14. Perl 5.8.8 Linux Проверил на других языках PHP, Javascript, (и как сказали C#) - 13 |
| Автор: Ignat 11.5.2007, 18:31 |
| Господа, я не претендую на хорошее знание сей, но ткните меня носом в UB. UB у нас будет в случае использования постфиксного инкремента, когда переменная для последующих операций берется по значению. В случае же префиксного инкремента результат операции инкремента всегда будет возвращен по ссылке. Приоритет инкремента всегда выше сложения (не путайте с унарной операцией +). Следовательно результат данного выражения в C/C++ гарантирован. Пожалуйста, поправьте, мне самому стало интересно |
| Автор: Любитель 11.5.2007, 19:00 | ||
| Ignat, по-моему именно эту ссылочку уже приводили, но всё же: http://www.research.att.com/~bs/bs_faq2.html#undefined - из хоум пйдж Бьярни Строуструпа. Добавлено через 4 минуты и 55 секунд
|
| Автор: _stranger_ 11.5.2007, 19:24 | ||
| и еще дополнение к вышесказанному: ISO/IEC 14882 C++ 5. Expressions. Clause 4
перевод на русский: между последовательными точками исполнения скалярный объект может меняться не более одного раза в результате вычисления выражения. ... Иначе результат не определен (UB). |
| Автор: Hurricane 11.5.2007, 19:26 | ||
Это можно как-то гарантировать? |
| Автор: Promitheus 11.5.2007, 19:38 | ||
Может быть они в С++ всё так и задумали. Идём слева направо встречаем ++i, меняем содержимое на +1 , далее встречаем +, смотрим , что далее ++i у него больше приоритет, выполняем его, далее встречаем +, но за ним ++i - выполняем. А потом уже выполняем сложение, но в качестве аргументов не значение числовое, а значание которое находится по адресу в памяти у переменной i. Т.е. при выполнении операций он запоминает не числовое значение, а указатель на область памяти, а потом выполняет с этими указателями операции более низкого приоритета. Это то, как мне видется такое поведение компилятора. Впринципе, нечего необычного в поведении нету. Это чисто мои догадки, как на самом деле реализовано, я естественно не знаю. На асме бы всё это надо написать.... мож понятнее будет. |
| Автор: nickless 11.5.2007, 19:47 |
| Я не понимаю, ну зачем зря гадать что получится, написано UB, значит UB. Конечно в каждом компиляторе это как-то реализовано, и в польшинстве случаев он выдаст один и тот же результат, но это абсолютно не гарантирует, что результат не будет другим со включеной оптимизацией, после изменения кода в другом файле проекта, с новой версией компилятора или после внезапного лунного затмения. Нравится плясать с бубном? |
| Автор: zkv 11.5.2007, 19:49 | ||||
я пошел еще дальше, и установил следующие факты:
Мне кажется, что компилятор интерпретирует выражение "+ ++i" как "прибавить 12" Завтра попробую продолжить эксперименты. PS Шутка PPS Наврал, в последнем не 48 получается, придется искать другое объяснение... |
| Автор: Любитель 11.5.2007, 19:52 |
Да ну. Ты уверен? На вскидку - после компайла MinGW и запуска, получаем 22 Андефинед бехаувер и всё! Хватит собственные варианты придумывать! Есть стандарт, который чётко определяет, что мы должны и когда получить. И он определяет, что в данной ситуации мы можем получить, что угодно. Всё! |
| Автор: Hurricane 11.5.2007, 19:58 | ||
Ай лайк йор джёрмен аксент! |
| Автор: Promitheus 11.5.2007, 20:13 | ||
Любитель,
В 6 Билдере прям в конструктор формы затолкай и откомпили, посмотришь, что получится - 24. __ Ну вообще да это какое-то шаманство ... i=++i + ++i + ++i + ++i + ++i; полтос выдаёт |
| Автор: Любитель 11.5.2007, 20:22 |
| Млин, уже обсудили. В билдере - 24, в MinGW - 22. Где-нибудь 23. Теоритечески может получится, скажем 115. Это будет формально удовлетворять стандарту, ибо по стандарту неизвестно, что должно получиться. А как правильно произносить? А то интересно стало А так - ракладки лень переключать |
| Автор: EvgenZ 11.5.2007, 20:23 |
| //это уже на BrainFuck смахивает ))))) Я знал, что без скобочек такое писать нельзя, но думал, что можно так (++i) + (++i); |
| Автор: Hurricane 11.5.2007, 20:59 | ||
Ну, по последним указаниям ЦК ВЦСПС что-то вроде Андифайнд Бихейвьёр. |
| Автор: JackYF 11.5.2007, 20:59 |
Насколько мне позволяет мой английский - "андефайнед бихавиэр" |
| Автор: nickless 11.5.2007, 22:03 |
http://www.answers.com/undefined http://www.answers.com/topic/behavior |
| Автор: BreakPointMAN 11.5.2007, 23:09 |
| Наверное, у всех временное помешательство, то ли звезды так расположены, то ли... На нескольких форумах в одно и то же время обсуждают одну и ту же тему... Бррр... Вы проhttp://alenacpp.blogspot.com/2005/11/sequence-points.html что-нибудь слышали? |
| Автор: Daevaorn 11.5.2007, 23:17 |
тут про них уже говорили |
| Автор: Любитель 11.5.2007, 23:45 |
| [offtop] На behavior у меня почему-то звук не открывается Мои преогромнейшие извинения за тягчайшее нарушение правил инглиш спикинг [/offtop] |
| Автор: Hurricane 12.5.2007, 00:44 | ||||
Молодец!
Любитель, ну это же шутка была... Все, обещаю больше не хулиганить с оффтопами. |
| Автор: JackYF 12.5.2007, 00:59 |
Занимательно. Но это теория. А то, что обсуждаемое выражение приводит к UB, и так уже выяснили. |
| Автор: Любитель 12.5.2007, 01:08 |
эээ... а я типа серьёзно говорю что ли |