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

Поиск:

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


Опытный
**


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

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



Вообщем проблемка у меня следующего характера. Есть код:
Код

int a=5, x=2;
a = ( a-- | x<<2 ) & (a<<2);
printf("%d\n", a);

Если я считаю вручную это выражение, то получается (0100 | 1000) & (10100) = 01100 & 10100 = 100 = 4. Если проверяю все это выражение в C++ получается 3. Если по частям, то левая часть равна 12, правая 20, 12 & 20 = 4.

В чем тут загвоздка?  smile
PM MAIL ICQ   Вверх
Sartorius
Дата 19.2.2009, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

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



a-- уменьшит a на 1 но значение этого выражения - a до изменения. Т.е 5. Да и в правой части логического умножения a уже изменено

Это сообщение отредактировал(а) Sartorius - 19.2.2009, 17:23
PM MAIL ICQ   Вверх
Lazin
Дата 19.2.2009, 17:32 (ссылка) |    (голосов:7) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 27
Всего: 154



это undefined behavior
PM MAIL Skype GTalk   Вверх
Kurganec
Дата 19.2.2009, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



мне кажется дело в постфиксе "--"

попробуй так:
Код

--a;


PM MAIL ICQ Skype   Вверх
vinter
Дата 19.2.2009, 18:59 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Kurganec, Lazin дал вполне однозначный ответ


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


Опытный
**


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

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



Извините за глупый вопрос. Почему именно undefined behaviour?


--------------------
user posted image
PM MAIL   Вверх
Dem_max
Дата 19.2.2009, 19:57 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 4
Всего: 39



лучше так
Код

a = ( (a--) | (x<<2) ) & (a<<2);



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
mes
Дата 19.2.2009, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(cutwater @  19.2.2009,  18:38 Найти цитируемый пост)
Извините за глупый вопрос. Почему именно undefined behaviour? 


попробуйте (мысленно) понаблюдать  за поведением этого примера
Код

a= --a1 + a2; //1
a= а2 +  --a2; //2

при таком вступление
Код

int a =5;
int a1=a;
int a2=a;

и таком :
Код

int a =5;
int& a1=a;
int& a2=a;

во втором случае этот код альтернативен следующему
Код

a= --a + a; //1
a= а +  --a; //2

результат которого зависит от факторов трансляции выражения и по стандарту не определен.

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


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


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


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

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



Цитата(Dem_max @  19.2.2009,  18:57 Найти цитируемый пост)
лучше так    
a = ( (a--) | (x<<2) ) & (a<<2);

 smile неа..проблема с UB не из за скобок..

если судить потому, чего хотел получить в результате тс:
Цитата(Ground @  19.2.2009,  16:13 Найти цитируемый пост)

Если я считаю вручную это выражение, то получается (0100 | 1000) & (10100) = 01100 & 10100 = 100 = 4.

то лучше  так :
Код

a = ((a-1) | x<<2) & a<<2;


Это сообщение отредактировал(а) mes - 19.2.2009, 20:21


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


Опытный
**


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

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



mes, благодарю за разъяснение. 


--------------------
user posted image
PM MAIL   Вверх
vinter
Дата 19.2.2009, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Цитата(cutwater @  19.2.2009,  20:38 Найти цитируемый пост)
Извините за глупый вопрос. Почему именно undefined behaviour?

дополню меса: тут два изменения одной переменной в одной точке следования, по стандарту это UB.


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


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


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

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



Цитата(vinter @  19.2.2009,  19:39 Найти цитируемый пост)
тут два изменения одной переменной в одной точке следования

что то изменение я нашел только одно... smile 


Это сообщение отредактировал(а) mes - 19.2.2009, 21:33


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


Explorer
****


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

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



Цитата(mes @  19.2.2009,  22:33 Найти цитируемый пост)
что то изменение я нашел только одно... 

1. a = expression
2. a--

Добавлено через 3 минуты и 51 секунду
Цитата(mes @  19.2.2009,  21:02 Найти цитируемый пост)
факторов трансляции выражения и по стандарту не определен.

это кстати не верно, последовательность вычислений тут вообще не причем, тут все проблемы с sequence points


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


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


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

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



Цитата(vinter @  19.2.2009,  20:45 Найти цитируемый пост)
1. a = expression
2. a--

т.е
Код

 int b= --a + a; 

уже не UB ?  smile 


Цитата(vinter @  19.2.2009,  20:45 Найти цитируемый пост)

это кстати не верно, последовательность вычислений тут вообще не причем, тут все проблемы с sequence points 

a кто говорил о причинности в последовательности вычислений ? зависимость от последовательности приводилось лишь для более легкого понимания данной проблемы.
да проблема с sequence points , но достаточно одного изменения и двойного использования этого значения в одной точке следования  smile 





Это сообщение отредактировал(а) mes - 19.2.2009, 22:07


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


Explorer
****


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

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



Цитата(mes @  19.2.2009,  23:05 Найти цитируемый пост)
уже не UB ?  

не UB

Цитата(mes @  19.2.2009,  23:05 Найти цитируемый пост)
 но достаточно одного изменения и двойного использования этого значения в одной точке следования  

нет


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


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


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

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



Цитата(vinter @  19.2.2009,  21:10 Найти цитируемый пост)
нет 

vinter, давайте для начала проведем эксперемент.. у Вас VS ? что дает  нижеприведенный код ?
Код

int a2=5; int a1=5;
int b= --a1 + a1;
int c= a2 + --a2;
std::cout << b<< " "<< c<< std::endl;




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


Explorer
****


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

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



Цитата(mes @  19.2.2009,  23:34 Найти цитируемый пост)
у Вас VS ?

ага

Цитата(mes @  19.2.2009,  23:34 Найти цитируемый пост)
что дает  нижеприведенный код ?

то, что и должен 8 8

mes, нет тут UB.


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


Опытный
**


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

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



Всем спасибо за помощь!

PM MAIL ICQ   Вверх
mes
Дата 20.2.2009, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(vinter @  20.2.2009,  05:17 Найти цитируемый пост)
то, что и должен 8 8

т.е каждое слагаемое расценивалось как 4 ? 
не будем сейчас задаваться вопросом о правильности результата,
просто немного усложним пример :
Код

int b= --a1 + a1*2; 
int c= a2*2 + --a2;
// gcc : 12 14 

Код

int b= --a1 + a1/2;
int c= a1/2 + --a2;
//gcc: 6 6

что теперь получается и как это объяснить ?


Это сообщение отредактировал(а) mes - 20.2.2009, 13:21


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


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(mes @  20.2.2009,  12:25 Найти цитируемый пост)
что теперь получается и как это объяснить ?

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



--------------------
PM MAIL   Вверх
vinter
Дата 20.2.2009, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Цитата(mes @  20.2.2009,  13:25 Найти цитируемый пост)
 как это объяснить ?

приоритетом операций  smile

Добавлено через 53 секунды
Цитата(zim22 @  20.2.2009,  13:52 Найти цитируемый пост)
что порядок вычисления подвыражений не определён...

четко определен приоритетами.


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


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


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

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



Цитата(vinter @  20.2.2009,  12:16 Найти цитируемый пост)

приоритетом операций  

т.е у "* " и "/" разные приорететы по отношению к  "--" ?



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


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



У меня в книжечке написано, что :
"За исключением логических операторов AND и OR, порядок вычисления парных операторов остается неопределенным, что обеспечивает компилятору свободу оптимизации кода."
Код

// Упс! Язык не определяет порядок обработки
if (ia[index++] < ia[index])



--------------------
PM MAIL   Вверх
mes
Дата 20.2.2009, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(zim22 @  20.2.2009,  12:28 Найти цитируемый пост)
if (ia[index++] < ia[index])

о! хороший пример  smile как раз по нашей теме, о кол-ве изменений в точке следования smile
демонстрация гораздо нагляднее )


Это сообщение отредактировал(а) mes - 20.2.2009, 13:37


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


Explorer
****


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

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



Цитата(mes @  20.2.2009,  14:24 Найти цитируемый пост)
т.е у "* " и "/" разные приорететы по отношению к  "--" ?

mes, вот чесное слово устал ты уже, открой таблицу приоритетов.. префиксный -- приоритетней всех арифметических операций.
Мне больше тут нечего сказать.


Цитата(mes @  20.2.2009,  14:37 Найти цитируемый пост)
о! хороший пример   как раз по нашей теме, о кол-ве изменений в точке следования 

это unspecified behavior, чувствуешь разницу с undefined?  smile 


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


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


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

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



..

Это сообщение отредактировал(а) mes - 20.2.2009, 17:51


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


Explorer
****


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

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



mes, значит в  gcc баг, VS выдает все как должно быть

Добавлено через 1 минуту и 5 секунд
а попробуй так
Код

int b= (--a1) + (a1*2); 
int c= a2*2 + (--a2);

это абсолютный эквивалент твоей записи


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


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


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

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



Цитата(vinter @  20.2.2009,  16:43 Найти цитируемый пост)
mes, вот чесное слово устал ты уже, открой таблицу приоритетов.. префиксный -- приоритетней всех арифметических операций.
Мне больше тут нечего сказать.

ну вот последний пример  :
Код

// gcc :
{ 
int a=1, b=1;
cout << a + (b - b) + ++a << endl; // 4
}{
int a=1, b=1;
cout << a + b - b + ++a << endl; // 3
}

интересно как в данном примере сказывается приоритет опeраций на разном результате ?

Добавлено через 3 минуты и 24 секунды
Цитата(vinter @  20.2.2009,  16:52 Найти цитируемый пост)
а попробуй так

результат как и прежде

Добавлено через 11 минут и 56 секунд
Цитата(vinter @  20.2.2009,  16:43 Найти цитируемый пост)
то unspecified behavior, чувствуешь разницу с undefined?  smile 

не очень.. smile 


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


Explorer
****


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

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



Цитата(mes @  20.2.2009,  19:23 Найти цитируемый пост)
интересно как в данном примере сказывается приоритет опeраций на разном результате ?


mes, как мне кажется gcc бажит, VC в обоих 4 выдает.

Цитата(mes @  20.2.2009,  19:23 Найти цитируемый пост)
результат как и прежде

Цитата(vinter @  20.2.2009,  18:52 Найти цитируемый пост)
значит в  gcc баг


Цитата(mes @  20.2.2009,  19:23 Найти цитируемый пост)
не очень.. 

я не понимаю как ссылку выложить на rsdn :(, короче сделаем относительный путь: rsdn\C++\deepC++
там найдешь, там статей не много.


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


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


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

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



Цитата(vinter @  20.2.2009,  16:52 Найти цитируемый пост)
int b= (--a1) + (a1*2); 

ИМХО это - UB, а1 читается 2 раза и изменяется 1 раз между точками следования, результат зависит от того, когда запишется изменение.
А gcc с -Wall кстати ворнинг выдаёт:
Код

bla.cpp:19: warning: operation on ‘a1’ may be undefined



--------------------
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
Дата 20.2.2009, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



nickless, тут одна точка, разберем выражение:
int b= (--a1) + (a1*2); 
т.к мы имеем два подвыражения, которые имеют одинаковый приоритет срабатывает lef-to-right-order. Следовательно первым отрабатывай декремент, затем умножение и только потом сложение. Тту не надо программирование знать это элементарная математика, т.е мы имеем два слагаемых, вычисление которых более приоритетно чем само сложение. Следовательно я не вижу даже unspecified, не то что undefined.. GCC смущает, не верю в тупость такого хорошего компилятора.. В результате есть небольшой ступор, но судя здравой логике - в gcc баг.


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


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


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

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



Цитата(vinter @  20.2.2009,  20:55 Найти цитируемый пост)
т.е мы имеем два слагаемых, вычисление которых более приоритетно чем само сложение

ага, только  какое из слагаемых подсчитается первым (декремент или умножение) мы не знаем... 



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


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


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

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



Цитата(vinter @  20.2.2009,  20:55 Найти цитируемый пост)
тут одна точка

Точка то одна, но даже если взять часть выражения:
Код

(--a1) + (a1*2)

тут между двумя точками мы 2 раза читаем и декрементируем а1.

Я думаю тут вот что действует:
Цитата

[Note: operators can be regrouped according to the usual mathematical rules only where the operators really
are associative or commutative.9) For example, in the following fragment
      int a, b;
      /*...*/
      a = a + 32760 + b + 5;
the expression statement behaves exactly the same as
      a = (((a + 32760) + b) + 5);
due to the associativity and precedence of these operators. Thus, the result of the sum (a + 32760) is
next added to b, and that result is then added to 5 which results in the value assigned to a. On a machine in
which overflows produce an exception and in which the range of values representable by an int is
[–32768,+32767], the implementation cannot rewrite this expression as
      a = ((a + b) + 32765);
since if the values for a and b were, respectively, –32754 and –15, the sum a + b would produce an
exception while the original expression would not; nor can the expression be rewritten either as
      a = ((a + 32765) + b);
or
      a = (a + (b + 32765));
since the values for a and b might have been, respectively, 4 and –8 or –17 and 12. However on a machine
in which overflows do not produce an exception and in which the results of overflows are reversible, the
above expression statement can be rewritten by the implementation in any of the above ways because the
same result will occur
. ]

Тут переполнение не ожидается, так что компилятор может и соптимизировать, кроме того:
Цитата

Except where noted, the order of evaluation of operands of individual operators and subexpressions of indi-
vidual 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.


Т.е. раз менять местами можно, а результат будет разный - получается UB.

Кстати, на VS результат всегда тот же не зависимо от оптимизации итд.?
Как насчет большего числа операндов?
edit Чуть подлиньше пример
Код

        int a1 = 5;
        int a2 = 5;
        int a3 = 5;
        int a4 = 5;
        int b = --a1 + a1*2 + a1*2 + a1*2;
        int c = a2*2 + --a2 + a2*2 + a2*2;
        int d = a3*2 + a3*2 + --a3 + a3*2;
        int e = a4*2 + a4*2 + a4*2 + --a4;
        cout << b << " " << c << " " << d << " " << e << endl;
        // gcc: 28 34 34 34


Это сообщение отредактировал(а) nickless - 20.2.2009, 22:24


--------------------
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
Дата 20.2.2009, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Цитата(mes @  20.2.2009,  23:04 Найти цитируемый пост)
мы не знаем...

а я знаю, они будут вычислены в пордяке приоритетов их операций!
Мне честно надоело уже говорить в стену, вот вам 2 ссылки: 
http://www.do2.rksi.ru/library/courses/demo/tema1_3.dbk
http://www.cyberguru.ru/programming/cpp/cp...up2-page39.html
там расписаны приоритеты операций.
Если есть, что возразить, то приводите факты большие чем вывод gcc.



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


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(nickless @  20.2.2009,  22:19 Найти цитируемый пост)
  // gcc: 28 34 34 34

VS 2008: 28 28 28 28

Это сообщение отредактировал(а) zim22 - 20.2.2009, 22:29


--------------------
PM MAIL   Вверх
vinter
Дата 20.2.2009, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



nickless, ты не сказал ничего нового, точнее ты не совсем верно трактовал стандарт.

Цитата(nickless @  20.2.2009,  23:19 Найти цитируемый пост)
the implementation in any of the above ways because thesame result will occur

у нас не same result
Цитата(nickless @  20.2.2009,  23:19 Найти цитируемый пост)
The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a fullexpression; otherwise the behavior is undefined.

вот оно, к чему относится Otherwise
Цитата(nickless @  20.2.2009,  23:19 Найти цитируемый пост)
Between the previousand next sequence point a scalar object shall have its stored value modified at most once by the evaluationof an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.


Добавлено через 2 минуты и 4 секунды
28 всюду, MSVC 9.0 full optimization


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


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


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

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



Цитата(vinter @  20.2.2009,  21:26 Найти цитируемый пост)
а я знаю, они будут вычислены в пордяке приоритетов их операций!

ну для начала воспользуемся одной из Ваших же ссылок(но заглянем на несколько страниц вперед) :

http://www.cyberguru.ru/programming/cpp/cp...up2-page41.html

Цитата

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

 smile 

Это сообщение отредактировал(а) mes - 20.2.2009, 22:51


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


Explorer
****


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

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



mes, ты вообще читаешь что пишут?
 ХВАТИТ ПРИВОДИТЬ ПРИМЕРЫ ВЫРАЖЕНИЙ ГДЕ ПРИОРИТЕТ ОДИНАКОВ!!!(звиняюсь)
В выражениях в этом топике приоритет не одинаков!!!

Добавлено через 5 минут и 42 секунды
давайте немного отвлечемся и представим, что мы в 3-ем класе, нам дают задание сказать результат выражения: 7*8 + 7*8.
Сколько будет? как тут можно трактовать двояко?

Добавлено через 10 минут и 3 секунды
icc: все 28


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


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


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

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



Цитата(vinter @  20.2.2009,  21:26 Найти цитируемый пост)
они будут вычислены в пордяке приоритетов их операций!

В таком случае такой код был бы вполне легитимен:
Код

i++ + ++i

если бы это выполнялось в порядке приоритетов операций, было бы: преинкремент -> плюс -> постинкремент. Однако это известный вариант UB.
Так как исключений из правил тут быть не должно, думаю что "i + ++i" тоже должен быть UB (хотя причина немного другая, i изменяется только один раз).

Цитата(vinter @  20.2.2009,  21:26 Найти цитируемый пост)
Если есть, что возразить, то приводите факты большие чем вывод gcc.

Точно такого примера пока не нашел, но есть такое выражение:
Код

i*(++i)

взято отсюда: http://gcc.gnu.org/bugs.html#nonbugs_c

Добавлено через 1 минуту и 4 секунды
ЗЫ Последний пример - UB

Добавлено через 3 минуты и 29 секунд
Кстати баг это или нет, но такой код компиляторозависим и лучше так не делать 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
Дата 20.2.2009, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Цитата(nickless @  21.2.2009,  00:15 Найти цитируемый пост)
взято отсюда: http://gcc.gnu.org/bugs.html#nonbugs_c

Цитата

The following expressions have unpredictable results:
...
i*(++i)                 /* special case with foo=="operator*" */
....

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

Цитата(nickless @  21.2.2009,  00:15 Найти цитируемый пост)
В таком случае такой код был бы вполне легитимен:

нет, тут срабатывает правила о sequence point. 2 изменеyния в пределах одной точки -  UB

Цитата(nickless @  21.2.2009,  00:15 Найти цитируемый пост)
"i + ++i" тоже должен быть UB

нет, сначала выполняется ++, потом +
### ошибок, лучше пойду  спать smile

Это сообщение отредактировал(а) vinter - 20.2.2009, 23:24


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


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


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

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



Цитата(vinter @  20.2.2009,  22:22 Найти цитируемый пост)
полная чушь, GCC идет лесом, у скобок приоритет выше чем у множения, а значит они выпеолняются первымси.

Зря ты так категорично, gcc тоже не дураки писали smile 

Поискал еще немного, похоже дело в этом:
Цитата(nickless @  20.2.2009,  21:19 Найти цитируемый пост)
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.

понять сложновато, но ИМХО это означает "доступ к предыдущему значению допустим лишь для вычисления значения, которое будет сохранено"
Т.е. никакого чтения после того как значение было сохранено, даже теоретическая возможность этого есть UB.

Сцылки:

http://open-std.org/jtc1/sc22/wg14/www/docs/n1188.pdf
Речь идёт о sequence points и "alowable orderings", вот этих:
Цитата(nickless @  20.2.2009,  21:19 Найти цитируемый пост)
the order of evaluation of operands of individual operators and subexpressions of indi-
vidual expressions, and the order in which side effects take place, is unspecified

даётся пример что одна лишь возможность перестановки subexpressions таким образом, что переменная может быть изменена до чтения - это уже UB

http://open-std.org/jtc1/sc22/wg14/www/docs/n1008.htm искать слово "prior"
Предложение более внятного объяснения вышеприведённой цитаты стандарта, как пример UB даётся:
Код

   Note that the following expressions, with apparently similar
   intent, all involve undefined behaviour:

       z = x + (x = 8, 0);
       z = x++ + x;
       z = x++ + (x = 8, 0);


http://www.embedded.com/story/OEG20020625S0041 искать "prior"
Объяснение этого самого "shall be accessed only to determine the value to be stored"


Короче если ты всё еще считаешь что это не UB, давай ссылку на обсуждение стандарта или хотя-бы похожий пример для VS откуда-нибудь с MSDN.


ЗЫ ИМХО стоит отделить обсуждение стандарта в общие вопросы


--------------------
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, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



http://msdn.microsoft.com/en-us/library/d45c7a5d(VS.71).aspx
http://msdn.microsoft.com/en-us/library/yck2zaey(VS.71).aspx

Короче я нигде не нашел, почуму же 
Цитата(vinter @  21.2.2009,  00:22 Найти цитируемый пост)
i*(++i)  

дает UB, кроме gcc'шной багзиллы. Какие то туманные намеки на стандарт, ничего конкретного.


Цитата(nickless @  21.2.2009,  02:02 Найти цитируемый пост)
доступ к предыдущему значению допустим лишь для вычисления значения, которое будет сохранено

ну и? а у нас не так? для чего еще оно используется?

Цитата(nickless @  21.2.2009,  02:02 Найти цитируемый пост)
 z = x++ + x;

это не undefined, а unspecified. А у нас в примере был префиксный оператор, о чем я в каждом посту напоминаю, а вы это просто игнорите...
Цитата(nickless @  21.2.2009,  02:02 Найти цитируемый пост)
Т.е. никакого чтения после того как значение было сохранено, даже теоретическая возможность этого есть UB

а я это понимаю как "нельзя второй раз изменять"

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

Этот пример полностью укладывается в порядок выполнения. Снчала вычисляется выражение в скобках, пооисходит сохранение нового значения i и только потом умножение.



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


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


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

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



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

С порядком выполнения зависимых инструкций никто не спорит. Но вот чтение с памяти переменной i может быть произведено еще до выполнения операции инкремента.
если подойти с другой стороны и раскрыть выражение то получится :
Код

operator*(i, operator ++(i));

а порядок вычисления аргументов функции также неопределен.


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


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


Explorer
****


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

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



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

Код

operator*(unspecified_i_for_gcc, i_incremented_yet);

вот что будет


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


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


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

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



Цитата(vinter @  21.2.2009,  11:13 Найти цитируемый пост)
вот что будет 

как бы то не было, gcc не нарушает стандарта, а вот писать код руководствуясь псевдоправильным поведением студии опасно.  smile 


--------------------
PM MAIL WWW   Вверх
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.1233 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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