реклама на сайте
подробности

 
 
6 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> фича компиляторв, инкремент переменной
zhevak
сообщение May 11 2007, 11:25
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



На форуме программистов (здесь http://www.rsdn.ru/Forum/?mid=2481623) с пацанами сейчас подняли интересную тему. Думаю, что си-шникам тоже следует остерегаться подобного кода. В двух словах проблема состоит в том, как компилятор должен понимать оператор инкремента.



int i;
int x;

i = 5;
x = ++i + ++i;



Чему в результате будет равно х ?

Прикол в том, что MS VC++ 6.0 и VC++.NET дают результат, равный 14. Майкрософтовский C# и IAR говорят, что х = 13. А более всего удивил Watcom -- у него результат зависит от того, включена-ли оптимизация или нет... 07.gif

Я, конечно, понимаю, что код, который обсуждается, несколько далек от жизни, но все же, знать о таких прибабахах -- надо.

Вечером дома, попробую еще в CodeVision эту фичу покрутить.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
vromanov
сообщение May 11 2007, 11:29
Сообщение #2


Участник
*

Группа: Новичок
Сообщений: 70
Регистрация: 27-03-07
Пользователь №: 26 533



Тут все просто. По стандарту результат исполнения такого кода не определен. Тот, кто пишет такой код - сам себе злобный буратино.
Go to the top of the page
 
+Quote Post
Ivan_Kov
сообщение May 11 2007, 11:33
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 174
Регистрация: 30-10-06
Из: г. Курск
Пользователь №: 21 787



Проблема стара как "С"...
Скобки используйте и все дела.
Go to the top of the page
 
+Quote Post
amw
сообщение May 11 2007, 11:33
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



GCC 3.4.5
gcc -o x x.c
x = 14
gcc -Os -o x x.c
x = 14
gcc -O0 -o x x.c
x = 14
gcc -O1 -o x x.c
x = 14
gcc -O2 -o x x.c
x = 14
gcc -O3 -o x x.c
x = 14


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 11:57
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(zhevak @ May 11 2007, 14:25) *
как компилятор должен понимать оператор инкремента.

Понимать он должен правильно smile.gif В данном выражении префиксные инкременты имеют максимальные приоритеты, посему формально при тупом исполнении 14, но выражение глупозапутанное и как раз тот случай, когда оптимизаторы 'ломаются' sad.gif. Просто так писать не надо!
И насчет слова 'оптимизация' - она очень разная бывает, у меня, например, Watcom при включении в проект со вполне любовно подобранной оптимизацией без вопросов выдал 14.
A IAR честно предупредил, что не понимает такой хрени и за результат не ручается.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
vromanov
сообщение May 11 2007, 12:39
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 70
Регистрация: 27-03-07
Пользователь №: 26 533



не страдайте фигней.
Вот вам выдержка из стандарта С++
i = ++i + i //the behavior is unspecified
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 12:42
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(vromanov @ May 11 2007, 15:39) *
не страдайте фигней.
Вот вам выдержка из стандарта С++
i = ++i + i //the behavior is unspecified

Смотрим внимательно и находим одно отличие:
Код
i= ++i + i;
x= ++i + i;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
vromanov
сообщение May 11 2007, 12:51
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 70
Регистрация: 27-03-07
Пользователь №: 26 533



Как любителю стандартов, вам надо было не искать отличия, а пойти почитать стандарт.
Там написано, что при наличии сторонних эффектов но описанных в стандарте поведение не определено. Тут как раз имеем сторонний эффект не описанный в стандарте.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 13:13
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(vromanov @ May 11 2007, 15:51) *
Тут как раз имеем сторонний эффект не описанный в стандарте.

Тут (x= ++i + i) в отличии от(i = i++ + i) его нет.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
dxp
сообщение May 11 2007, 13:37
Сообщение #10


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(vromanov @ May 11 2007, 19:51) *
Как любителю стандартов, вам надо было не искать отличия, а пойти почитать стандарт.
Там написано, что при наличии сторонних эффектов но описанных в стандарте поведение не определено. Тут как раз имеем сторонний эффект не описанный в стандарте.

Побочные эффекти возникают, когда объект меняется больше одного раза между точками следования. Очевидно, что в рассматриваемом выражении x= ++i + i, объект i меняется всего один раз.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 11 2007, 14:22
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(dxp @ May 11 2007, 16:37) *
Очевидно, что в рассматриваемом выражении x= ++i + i, объект i меняется всего один раз.
А в исходном ++i + ++i?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 14:29
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Сергей Борщ @ May 11 2007, 17:22) *
А в исходном ++i + ++i?

В исходном - не хорошо c точки зрения потенциального возникновения неоднозначности sad.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Ivan_Kov
сообщение May 11 2007, 15:32
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 174
Регистрация: 30-10-06
Из: г. Курск
Пользователь №: 21 787



Я вот смотрю, и не могу никак понять, что за нужда заставляет человека использовать подобные конструкции?
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 11 2007, 15:37
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(vromanov @ May 11 2007, 15:29) *
Тут все просто. По стандарту результат исполнения такого кода не определен. Тот, кто пишет такой код - сам себе злобный буратино.



Угу

Цитата
Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.70)


Цитата
If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the
behavior is undefined.


Цитата
1 undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable
results, to behaving during translation or program execution in a documented manner characteristic of the
environment (with or without the issuance of a diagnostic message), to terminating a translation or
execution (with the issuance of a diagnostic message).


В выражении ++i + ++i значение i изменяется два раза, следовательно, по стандарту результат неопределенный.

В выражении ++i + i значение i считывается два раза, один раз для вычисления нового сохраняемого значения i слева, второй раз - при вычислении правой части сложения, следовательно, по стандарту результат неопределенный.

Обратите внимание, что ключевой момент для применения правила об одном считывании - значение переменной i модифицируется в выражении.


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
vromanov
сообщение May 11 2007, 16:08
Сообщение #15


Участник
*

Группа: Новичок
Сообщений: 70
Регистрация: 27-03-07
Пользователь №: 26 533



Удивительно, что столь очевидная вещь собрала столько сломанных копий. Есть кучу куда более прикольных особеностей в с++ smile.gif
Go to the top of the page
 
+Quote Post

6 страниц V   1 2 3 > » 
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 15:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01485 секунд с 7
ELECTRONIX ©2004-2016