Когда происходит post increment?
От: Silver_s Ниоткуда  
Дата: 29.04.02 11:04
Оценка:
post decrement/increment должен выполняться после вычисления значения выражения, но что нужно понимать под выражением?

int i=0,j1,j2;
if( (j1=(i++ + i++))!=13 && (j2=(i++ + i++))!=13 );

после выполнения (на VC6): j1==0; j2==4
Т.е. получается что первое условие и второе это разные выражения?
Или стандартом не оговорено когда надо делать пост операции?
Re: Когда происходит post increment?
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.04.02 11:08
Оценка:
Здравствуйте Silver_s, Вы писали:

SS>post decrement/increment должен выполняться после вычисления значения выражения, но что нужно понимать под выражением?


SS>Или стандартом не оговорено когда надо делать пост операции?


Вот здесь был большой разговор на эту тему:
http://www.rsdn.ru/forum/message.asp?mid=48027
Автор: Vi2
Дата: 23.04.02
Re[2]: Когда происходит post increment?
От: Кодт Россия  
Дата: 29.04.02 11:23
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>Здравствуйте Silver_s, Вы писали:


SS>>post decrement/increment должен выполняться после вычисления значения выражения, но что нужно понимать под выражением?


SS>>Или стандартом не оговорено когда надо делать пост операции?


DG>Вот здесь был большой разговор на эту тему:

DG>http://www.rsdn.ru/forum/message.asp?mid=48027
Автор: Vi2
Дата: 23.04.02


Тут сразу несколько граблей раскидано.
1) undefined behavior (неопределенное поведение) при неоднократном использовании автоинкремента в выражении
2) правила вычисления оператора &&
3) не инициализированные переменные (j1, j2) (сработает вместе с оператором && )

Наконец, с учетом компиляции в режиме debug (без оптимизаций), мы получили весьма ожидаемый результат.

Вот что родил компилятор

[c]
i_1 = i; // i_1 = 0
i_2 = i; // i_2 = 0 (повезло, что постинкремент выполняется позже)
j1 = i_1 + i_2; // j1 = 0
ok_1 = j1 != 13; // ok_1 = true
i++; i++; // i = 2 (а вот и автоинкремент)

if(!ok_1) goto false_branch;

i_3 = i; // i_3 = 2
i_4 = i; // i_4 = 2
j2 = i_3 + i_4; // j2 = 4
ok_2 = j2 != 13; // ok_2 = true

if(!ok_2) goto false_branch;

true_branch:;
// true
....
goto end_if;

false_branch:;
// false
....

end_if:;

[/code]

При оптимизации — возможны любые, в том числе самые ужасные, результаты.
Перекуём баги на фичи!
Re[3]: Когда происходит post increment?
От: Кодт Россия  
Дата: 29.04.02 11:27
Оценка:
Здравствуйте Кодт, Вы писали:

Пардон, там еще должен быть i++; i++ второй раз.
И еще сорри за кривое форматирование.
Перекуём баги на фичи!
Re: Когда происходит post increment?
От: Андрей Тарасевич Беларусь  
Дата: 29.04.02 15:50
Оценка: 8 (2)
Здравствуйте Silver_s, Вы писали:

SS>post decrement/increment должен выполняться после вычисления значения выражения, но что нужно понимать под выражением?


SS>Или стандартом не оговорено когда надо делать пост операции?


Не оговорено. Все побочные эффекты должны возыметь место до следуюшей точки следования. Точнее сказать нельзя.

Постинкремент означает, что в выражении будет использовано значение переменной до инкремента. А когда кокретно поизойдет сам инкремент — никто не знает. Инкремент, если так захочет компилятор, может произойти даже до использования значения переменной в выражении.

Например, вот такой С++ код

int a, b;
...
a = b++ + 5;


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

mov     eax, b
inc     b
add     eax, 5
mov     a, eax


т.е. собственно инкремент переменной 'b' делается еще до того, как будет выполнено сложение с 5 и переменная 'a' получит новое значение. Тем не менее код ведет себя так, как должен вести себя именно постинкремент.
Best regards,
Андрей Тарасевич
Re: Когда происходит post increment?
От: flyker Россия  
Дата: 30.04.02 10:12
Оценка:
Здравствуйте Silver_s, Вы писали:

SS>post decrement/increment должен выполняться после вычисления значения выражения, но что нужно понимать под выражением?


SS>
SS>int i=0,j1,j2;
SS>if( (j1=(i++ + i++))!=13 && (j2=(i++ + i++))!=13 );
SS>

SS>после выполнения (на VC6): j1==0; j2==4
SS>Т.е. получается что первое условие и второе это разные выражения?
SS>Или стандартом не оговорено когда надо делать пост операции?

Оператор && разделяет выражения, но не является его елементом.

код

if( expression1 && expression2 )
{
    ......
}


Эквивалентен коду

if( expression1 )
{
    if( expression2 )
    {
        ......
    }
}


То есть если первое выражение не верно, то второе никогда не выполнится.
И наоборот оператор || заставит выполнится оба выражения.

P.S. Это к вопросу о выражениях, сорри если говорю прописные истины
Все гениальное — просто
Re[2]: Когда происходит post increment?
От: flyker Россия  
Дата: 30.04.02 10:23
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

АТ>Здравствуйте Silver_s, Вы писали:


SS>>post decrement/increment должен выполняться после вычисления значения выражения, но что нужно понимать под выражением?


SS>>Или стандартом не оговорено когда надо делать пост операции?


АТ>Не оговорено. Все побочные эффекты должны возыметь место до следуюшей точки следования. Точнее сказать нельзя.


АТ>Постинкремент означает, что в выражении будет использовано значение переменной до инкремента. А когда кокретно поизойдет сам инкремент — никто не знает. Инкремент, если так захочет компилятор, может произойти даже до использования значения переменной в выражении.


АТ>Например, вот такой С++ код


АТ>
АТ>int a, b;
АТ>...
АТ>a = b++ + 5;
АТ>


АТ>компилятор, если захочет, может странслировать вот в такой результирующий код


АТ>
АТ>mov     eax, b
АТ>inc     b
АТ>add     eax, 5
АТ>mov     a, eax
АТ>


АТ>т.е. собственно инкремент переменной 'b' делается еще до того, как будет выполнено сложение с 5 и переменная 'a' получит новое значение. Тем не менее код ведет себя так, как должен вести себя именно постинкремент.


Позволю не согласится

оператор + есть функция от двух переменных
перепишем его в виде plus(a, b)
таким образом
a++ + b
эквивалентно
plus(a++, b)
а здесь уже a+1 внутрь передаваться не будет никогда.
Может я чего-то не понимаю ???
Все гениальное — просто
Re[2]: Когда происходит post increment?
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 30.04.02 11:50
Оценка:
Здравствуйте flyker, Вы писали:

F>Оператор && разделяет выражения, но не является его елементом.

iso/iec 14882 5/1:
An expression is a sequence of operators and operands that specifies a computation.

Выражение содержит опреаторы и операнды. Оно состоит из опреаторов и операндов. Оператор — часть выражения. && — оператор.

F>P.S. ... сорри если говорю прописные истины

Истины, говоришь, говоришь?.. Может, книжку почитать сперва?
Алексей Кирдин
Re[3]: не совсем так
От: jazzer Россия Skype: enerjazzer
Дата: 30.04.02 13:11
Оценка:
Здравствуйте flyker, Вы писали:

F>оператор + есть функция от двух переменных

F>перепишем его в виде plus(a, b)
F>таким образом
F>a++ + b
F>эквивалентно
F>plus(a++, b)
F>а здесь уже a+1 внутрь передаваться не будет никогда.
F>Может я чего-то не понимаю ???

оператор есть функция только с синтаксической точки зрения, но не с точки зрения исполнения кода.
Вызов функции устанавливает по крайней мере 2 точки следования — до ее вызова и после, а арифметическое выражение не устанавливает точек следования внутри себя.
Поэтому тут нет эквивалентности.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Когда происходит post increment?
От: flyker Россия  
Дата: 30.04.02 14:06
Оценка:
Здравствуйте Kaa, Вы писали:

Kaa>Здравствуйте flyker, Вы писали:


F>>Оператор && разделяет выражения, но не является его елементом.

Kaa>iso/iec 14882 5/1:
Kaa>An expression is a sequence of operators and operands that specifies a computation.

Kaa>Выражение содержит опреаторы и операнды. Оно состоит из опреаторов и операндов. Оператор — часть выражения. && — оператор.


F>>P.S. ... сорри если говорю прописные истины

Kaa>Истины, говоришь, говоришь?.. Может, книжку почитать сперва?

Ну это вопрос терминологии
Все гениальное — просто
Re[3]: Когда происходит post increment?
От: Андрей Тарасевич Беларусь  
Дата: 30.04.02 15:58
Оценка:
Здравствуйте flyker, Вы писали:

F>Позволю не согласится


F>оператор + есть функция от двух переменных

F>перепишем его в виде plus(a, b)
F>таким образом
F>a++ + b
F>эквивалентно
F>plus(a++, b)
F>а здесь уже a+1 внутрь передаваться не будет никогда.
F>Может я чего-то не понимаю ???

Не понимаешь. Для скалярных типов 'operator ++' функций не является.
Best regards,
Андрей Тарасевич
Re[2]: Когда происходит post increment?
От: vladsm Россия  
Дата: 30.04.02 17:30
Оценка:
Здравствуйте flyker, Вы писали:

F>Оператор && разделяет выражения, но не является его елементом.


F>код


F>
F>if( expression1 && expression2 )
F>{
F>    ......
F>}
F>


F>Эквивалентен коду


F>
F>if( expression1 )
F>{
F>    if( expression2 )
F>    {
F>        ......
F>    }
F>}
F>


F>То есть если первое выражение не верно, то второе никогда не выполнится.

F>И наоборот оператор || заставит выполнится оба выражения.

Про оператор || не правильно.

if ( expr1 || expr2)
{
// do smth.
}


Здесь если expr1 – истинно, expr2 не выполняется.
Re[4]: Когда происходит post increment?
От: Андрей Тарасевич Беларусь  
Дата: 30.04.02 17:49
Оценка:
F>>оператор + есть функция от двух переменных
F>>перепишем его в виде plus(a, b)
F>>таким образом
F>>a++ + b
F>>эквивалентно
F>>plus(a++, b)
F>>а здесь уже a+1 внутрь передаваться не будет никогда.
F>>Может я чего-то не понимаю ???

АТ>Не понимаешь. Для скалярных типов 'operator ++' функций не является.


И это очень важная деталь. В письме от DarkGray есть ссылка на thread, где эта тонкость детально объясняется.
Best regards,
Андрей Тарасевич
Re: Когда происходит post increment?
От: Lummox  
Дата: 01.05.02 04:24
Оценка:
Здравствуйте Silver_s, Вы писали:

SS>post decrement/increment должен выполняться после вычисления значения выражения, но что нужно понимать под выражением?


SS>
SS>int i=0,j1,j2;
SS>if( (j1=(i++ + i++))!=13 && (j2=(i++ + i++))!=13 );
SS>

SS>после выполнения (на VC6): j1==0; j2==4
SS>Т.е. получается что первое условие и второе это разные выражения?
SS>Или стандартом не оговорено когда надо делать пост операции?

Вообще, и i++ и ++i делают одно и тоже, просто постфиксный инкремент ВОЗВРАЩАЕТ i, а префииксный — i+1, а в тот момент, как опрератор возвратил значение, i в любом случае увеличена на единицу, т.е.

int i=1,j=1;
int a,b;
a=i++;
b=++j;

тут и i и j равны 2, а вот a==1, b==2;
В отличье от себя — тебе я верю...
Re[2]: Когда происходит post increment?
От: Андрей Тарасевич Беларусь  
Дата: 01.05.02 15:48
Оценка:
Здравствуйте Lummox, Вы писали:

L>Вообще, и i++ и ++i делают одно и тоже, просто постфиксный инкремент ВОЗВРАЩАЕТ i, а префииксный — i+1, а в тот момент, как опрератор возвратил значение, i в любом случае увеличена на единицу, т.е.


Нет. Увеличено ли 'i' на единицу в тот момент, когда оператор "возвратил значение", или нет — никто не знает. Увеличение должно произойти не позже, чем управление дойдет до следующей точки следования. В какой конкретно момент оно призойдет — предсказать невозможно.
Best regards,
Андрей Тарасевич
Re[3]: Когда происходит post increment?
От: Lummox  
Дата: 03.05.02 02:26
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

АТ>Здравствуйте Lummox, Вы писали:


L>>Вообще, и i++ и ++i делают одно и тоже, просто постфиксный инкремент ВОЗВРАЩАЕТ i, а префииксный — i+1, а в тот момент, как опрератор возвратил значение, i в любом случае увеличена на единицу, т.е.


АТ>Нет. Увеличено ли 'i' на единицу в тот момент, когда оператор "возвратил значение", или нет — никто не знает. Увеличение должно произойти не позже, чем управление дойдет до следующей точки следования. В какой конкретно момент оно призойдет — предсказать невозможно.


Признаю, погорячился... Я имел в виду сказать, что об оператора делают одно и тоже за тем исключением, что возвращаемое значение у них разное
В отличье от себя — тебе я верю...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.