Задачка с башорга

ys

отодвинутый новичок
Странный топик.
Как сказал phprus, происходит следующее:

'++' - инкремент, более приоритетный, и, главное, находиться ДО операнда т.е. является пре инкрементом (сначало значение увеличивается на 1, а потом используется).

В Си сначала вычисляются аргументы и при отсутствии оптимизации получается, что число 5 увеличивается два раза и получается - 7.

Далее, сами текущие значения переменной сумируется и получается - 14.


Что я делаю не так?
 

StUV

Rotaredom
ys
хм... этот вариант уже описан в топе раз 10 (если не больше)
считаешь - этого не достаточно ? ;)
 

ys

отодвинутый новичок
StUV

> считаешь - этого не достаточно

Э. Это как про сулслика: "не видишь, а он есть"? :)
Понял, спасибо, раз 10 раз было до, меня можно убрать из этого топика.
 

Фанат

oncle terrible
Команда форума
ys
ты все перепутал.
14 получается в присутствии оптимизации.
когда сначала вычислаются аргументы, то получается 13.

а вот почему получается 14 - написано phprus, но ты как-то странно прочел.
 

Фанат

oncle terrible
Команда форума
нет, новолуние.
просто темы интересные на этом форуме бывают редко. очень
 

God

Новичок
Фанат
14 получается и без оптимизации, где-то уже асм выложен из VisualStudio.
 

HraKK

Мудак
Команда форума
cDLEON
Переменная занимает одну область памяти, по этому будет не
(5+1)+((5+1)+1) = 13
а
(5+1+1)+((5+1+1)+1) = 14

Но это мое очееень скромное имхо)
 

HraKK

Мудак
Команда форума
ну блин) понятно что очичатался)
(5+1+1)+((5+1+1)) = 14

* пошел читать мат часть за 3 класс
 

romy4

invoke [brain]
God
а каким образом оптимизация должна влиять на исходный результат, кроме как более быстрым вычислением?
 

God

Новичок
romy4
Это был ответ на реплику Фаната: "... 14 получается в присутствии оптимизации..."
 

AnToXa

prodigy-одаренный ребенок
господа, не пора ли прекратить? algo все же написал. :D

Сергей Тарасов и все все.
стандарт языка C++ (C - аналогично, т.к. семантика абстрактной машины практически идентична) оговаривает эту ситуацию, а именно в пункте 5/4. вчера писал популярное объяснение для товарища, запощу сюда, надеюсь поможет.

короче там undefined behaviour, но скорее всего будет 14. с примитивами просто иначе довольно трудно сделать :)

смотри.
1. порядок вычисления аргументов функции не определен, но все параметры вычисляются до входа в функцию.
2. собсна сам вход в функцию и выход из нее - это т.н. sequence point, это момент когда гарантируется, что все side effects, от операций в этом выражении случились (eng. completed).
3. ; - это тоже sequence point.
4. side effects - это: вызовы библиотечных функций, и запись в volatile переменные, ++(примитив) - тоже в общем-то сюда попадает.
5. сообщается, что если переменная модифицируется дважды между sequence point-ами, то результат вычисления выражения неопределен, на самом деле не только выражения, а вообще всей программы.
++i - это load + inc + store, их два, seq point-ов между ними нет => undefined behavoiur, компилятор волен хоть код для полета на луну сгенерить.
dark-demon
или по твоему
code:
int i; ++i;
чем-то принципиально отличается от
code:
myclass i; ++i;
?
да, отличаются, т.к. для myclass - это вызов функции со всеми последствиями, т.е. два дополнительных sequence point-а (см. выше про них).

еще на тему можно почитать вот тут: http://rsdn.ru/Forum/Message.aspx?mid=48403#48403
 

romy4

invoke [brain]
dark-demon
мы и говорим о де-факто. то, что является перегрузкой оператора - уже не есть стандартной операцией
 

AnToXa

prodigy-одаренный ребенок
да, надо проконсультироваться с компиляторщиками, но имхо сам пункт 5/4, утверждающий(сорри, длинно, но стандарт - нудная штука :) ):
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual
expressions, and the order in which side effects take place, is unspecified.53) 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. Furthermore, the prior value shall be accessed only to determine the value to be stored.
The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined. [Example:
Код:
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented
—end example]
этот пункт позволяет компилятору в общем-то творить все что угодно в предположении, что переменная меняется всего раз между любыми "смежными" sequence point-ами. т.е. например сначала расклонировать значение по двум кусочкам sse регистра, потом сделать xadd для обеих за одну инструкцию, а потом передать в функцию (с предпологаемой оптимизацией - функция прям из sse регистра эти значения и заберет), т.е. результат будет вообще 12 :D

а может и правда сгенерить код для полета на луну ;)
 
Сверху