Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> С++ неверно высчитывает значение функции, Или я недочитал теории :) 
V
    Опции темы
vinter
Дата 21.2.2009, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(mes @  21.2.2009,  13:58 Найти цитируемый пост)
как бы то не было, gcc не нарушает стандарта

спорный вопрс я четкого регламента так и не нашел. Так, что видимо стандарт сам темнит в этой ситуации.



--------------------
Мой блог
PM MAIL WWW   Вверх
nickless
Дата 21.2.2009, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 2
Всего: 181



Хм, в MSDN тоже никакой конкретики, только на счет side effects есть:
http://msdn.microsoft.com/es-es/library/8a425116.aspx
Цитата

Since unary increment and decrement operations involve assignments, such operations can cause side effects, as shown in the following example:

x[i] = i++;

В примере постинкремент, но преинкремент тоже имеет side effect, так что он ИМХО ничем не лучше.

Цитата(vinter @  21.2.2009,  07:52 Найти цитируемый пост)
это не undefined, а unspecified

Почему unspecified когда там четко написано undefined? 

Цитата(vinter @  21.2.2009,  07:52 Найти цитируемый пост)
А у нас в примере был префиксный оператор, о чем я в каждом посту напоминаю, а вы это просто игнорите...

А чем он отличается от постфиксного? Ведь по стандарту разница лишь в возвращаемом значении ++i vs. i++, а момент, когда результат инкремента будет записан в переменную определён лишь точками следования, которая в примере
Код

y = ++x + x;

одна в конце выражения.

Цитата(vinter @  21.2.2009,  07:52 Найти цитируемый пост)
"нельзя второй раз изменять"

Про второй раз изменять там написано отдельно:
Цитата(nickless @  21.2.2009,  00:02 Найти цитируемый пост)
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.

это условие выполняется, а вот это:
Цитата(nickless @  21.2.2009,  00:02 Найти цитируемый пост)
Furthermore, the prior value shall be accessed only to determine the value to be stored.

нет.
Ты pdf читал? Там как раз про это.

Цитата(vinter @  21.2.2009,  07:52 Найти цитируемый пост)
В стандарте НЕТ четкого указания по порядку вычисления одинаковоприоритеных подвыражений, поэтому различные компиляторы творят, что хотят. Но зато есть приоритеты операций, которые, например gcc, игнорит

Приоритеты операций в данном случае не имеют значения, как и в a[i] = i++;


Цитата(vinter @  21.2.2009,  07:52 Найти цитируемый пост)
Этот пример полностью укладывается в порядок выполнения.

Порядок выполнения тут не нарушается, проблема в том, что выражение ++i имеет побочный эффект. По стандарту, результат побочного эффекта достигнет переменной к следующей точке следования, а не до оператора умножения.
Получается два возможных варианта:
[точка следования n] читаем i, инкрементируем, сохраняем новое значение, читаем i, складываем, [точка следования n+1]
[точка следования n] читаем i, инкрементируем, читаем i, складываем, сохраняем новое значение, [точка следования n+1]
Оба варианта следуют стандарту, а результат разный - слöедовательно это UB.

Цитата(vinter @  21.2.2009,  07:52 Найти цитируемый пост)
Снчала вычисляется выражение в скобках, пооисходит сохранение нового значения i и только потом умножение

Нет, порядок выполнения не влияет на сохранение нового значения. Если бы это было что-то вроде
Код

++i && a = i

то да, новое значение i было бы сохранено до присваивания, т.к. && определяет точку следования, а + или * точки следования не определяют.

Цитата(mes @  21.2.2009,  10:41 Найти цитируемый пост)
С порядком выполнения зависимых инструкций никто не спорит. Но вот чтение с памяти переменной i может быть произведено еще до выполнения операции инкремента.

+1

Цитата(mes @  21.2.2009,  10:41 Найти цитируемый пост)
если подойти с другой стороны и раскрыть выражение то получится :
...
а порядок вычисления аргументов функции также неопределен.

Это пример только для C++, в случае с C причина немного другая.



--------------------
user posted image

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
PM MAIL   Вверх
vinter
Дата 21.2.2009, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(nickless @  21.2.2009,  18:19 Найти цитируемый пост)
Хм, в MSDN тоже никакой конкретики, только на счет side effects есть:

там есть гарантия порядка выполнения, например что при < вычислен сначала будет левый аргумент.
Цитата(nickless @  21.2.2009,  18:19 Найти цитируемый пост)
А чем он отличается от постфиксного?

у префиксного наивысший приоритет, у постфиксного наинизший.
Цитата(nickless @  21.2.2009,  18:19 Найти цитируемый пост)
Furthermore, the prior value shall be accessed only to determine the value to be stored.

блин, а по твоему когда мы пишем просто x* мы как то вступаем в противоречие с этой фразой?


Цитата(nickless @  21.2.2009,  18:19 Найти цитируемый пост)
По стандарту, результат побочного эффекта достигнет переменной к следующей точке следования, а не до оператора умножения.

как это? т.е ты хочешь сказать, что изменения в переменных происходят только по завершении точки следования? Это 100% чушь, т.к в этом случае ни одно выражение не может быть построено. Пример с твоих слов:
x = y * ++z; UB, т.к z изменится ятолько по завершению эволюции выражения.



--------------------
Мой блог
PM MAIL WWW   Вверх
mes
Дата 21.2.2009, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(vinter @  21.2.2009,  17:36 Найти цитируемый пост)
x = y * ++z; UB, т.к z изменится ятолько по завершению эволюции выражения.

да z в памяти изменится только по завершению эволюции, но это не UB так как никто не использует эту память.
а то что предназначено для умножения как правый множитель (но это не z!)  будет иметь значение инкрементированого z.


P.S. мне кажется Вы упустили, что арифметические операции проходят не с ячейками памяти, а с регистрами
в которые вначале загружаются значения и из которых в дальнейшем результат записывается в память.
т.е значения которое отдала переменная для расчетов и которое в действительности хранится в ее памяти в определенные моменты времени отличаются..

Это сообщение отредактировал(а) mes - 21.2.2009, 19:03


--------------------
PM MAIL WWW   Вверх
nickless
Дата 21.2.2009, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 2
Всего: 181



Цитата(vinter @  21.2.2009,  17:36 Найти цитируемый пост)
блин, а по твоему когда мы пишем просто x* мы как то вступаем в противоречие с этой фразой?

Нет конечно

Цитата(vinter @  21.2.2009,  17:36 Найти цитируемый пост)
т.е ты хочешь сказать, что изменения в переменных происходят только по завершении точки следования? Это 100% чушь

Нравится тебе это или нет, но в стандарте так и написано:
Цитата

Evaluation of an expression may produce side effects. At certain specified points in the
execution sequence called sequence points, all side effects of previous evaluations shall
be complete
 and no side effects of subsequent evaluations shall have taken place.

The grouping of operators and operands is indicated by the syntax.72) Except as specified
later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation
of subexpressions and the order in which side effects take place are both unspecified.


Цитата(vinter @  21.2.2009,  17:36 Найти цитируемый пост)
Пример с твоих слов:
x = y * ++z; UB, т.к z изменится ятолько по завершению эволюции выражения.

Да, z изменится только после завершения эвалюации, но это не UB, т.к. z больше не используется, а результат выражения ++z чётко определён.

Добавлено через 1 минуту и 32 секунды
Цитата(nickless @  21.2.2009,  17:57 Найти цитируемый пост)
эвалюации

 smile 

ЗЫ Медленно я пишу...


--------------------
user posted image

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
PM MAIL   Вверх
vinter
Дата 21.2.2009, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(nickless @  21.2.2009,  19:57 Найти цитируемый пост)
Нравится тебе это или нет, но в стандарте так и написано

ок. Стандарт все таки более дебилен, чем я думал. Спасибо за дискуссию.



--------------------
Мой блог
PM MAIL WWW   Вверх
Ground
Дата 23.2.2009, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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
PM MAIL ICQ   Вверх
vinter
Дата 23.2.2009, 09:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(Ground @  23.2.2009,  09:46 Найти цитируемый пост)
a=(a--|x<<2)&(a<<2)

тут стопроцентный Undefined behavior
Цитата(Ground @  23.2.2009,  09:46 Найти цитируемый пост)
Первая говорит, что у постфиксного инкремента и декремента самый низний приоритет из операций, а префиксного самый высокий. Вторая ссылка утверждает что у них одинаковый приоритет. Кому верить?

лучше все таки верить Страуструпу. Но там не совсем верная таблица приведена. Сейчас открыл книгу приоритет постфиксных операций, выше чем префиксных..


--------------------
Мой блог
PM MAIL WWW   Вверх
Ground
Дата 23.2.2009, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 321
Регистрация: 27.2.2006
Где: Комсомольск

Репутация: нет
Всего: 1



Я просто пытаюсь понять алгоритм си.
Все дело в том, что в дальнейших вычислениях у меня есть квадратный корень, и при ответе a=4 (если считать выражение UB, и исправить это), у меня получается отрицательное значение под ним, а при a=3 (исходное выражение, без исправлений) все сходится. Т.е. программа считает как мне необходимо дальше по заданию. Возможно это ошибка в задании.

Если читать первую ссылку, то получается что у постфиксного декремента самый низкий приоритет, и тогда мы вычисляем (a|x<<2)&(a<<2), а потом находим декремент этого выражения, то у меня получится 3, как и у программы. В резуальтате выходит, что дело в приоритете операций.

Это сообщение отредактировал(а) Ground - 23.2.2009, 10:20
PM MAIL ICQ   Вверх
vinter
Дата 23.2.2009, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Ground, не читай первую ссылку smile Я сам ее счиатл верной, сейчас открыл Страуструпа и понял, что та ссылка не верна. Попробуй найди Страуструп 3-е издание, там наиболее верная таблица.


--------------------
Мой блог
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0568 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.