URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 981
[ Назад ]

Исходное сообщение
"Провокационный вопрос  по C"

Отправлено Soldier , 18-Сен-02 09:55 
Дано

y=1;
x=++y + ++y + ++y;

Чему равен x ?


Содержание

Сообщения в этом обсуждении
"RE: Провокационный вопрос  по C"
Отправлено erg , 18-Сен-02 14:42 
>Дано
>
>y=1;
>x=++y + ++y + ++y;
>
>Чему равен x ?

Хороший вопрос !
Прикинув то как это "должно быть" по моему инению "2+3+4" в любой последовательности получаем "9". Но написав программу VC6.0 дал ответ "10",
gcc2.96 поддержал его. Но "java" думет как я, и уверенно отвечает "9".
Если у кого есть какие-то соображения или эксперименты хотелось бы их увидеть.


"RE: Провокационный вопрос  по C"
Отправлено Soldier , 18-Сен-02 15:57 
>Прикинув то как это "должно быть" по моему инению "2+3+4" в любой
>последовательности получаем "9". Но написав программу VC6.0 дал ответ "10",
>gcc2.96 поддержал его. Но "java" думет как я, и уверенно отвечает "9".
>
>Если у кого есть какие-то соображения или эксперименты хотелось бы их увидеть.
>

Я тоже думаю, что должно быть 9, но Бормондовые компилеры до 5 версии выдают 12, lcc (есть такой неказистый компилер) 9, awk 9, perl 10, gcc 10.

Если 12 еще можно объяснить, то 10 в gcc и perl по-моему это просто bug. Более того если написать так x=++y + (++y + ++y), то gcc дает 12.

Дурдом короче.


"RE: Провокационный вопрос  по C"
Отправлено XMan , 18-Сен-02 16:04 
Вобщем, если записывать в обратной польской записи, то оно сразу понятно становится (если ты, конечно с ней знаком). Вот упрощенный вариант:

1. y++  (y=y+1 => y=2)
2. y++  (y=y+1 => y=3)
3. +     (x=y+y => y=6)
4. y++ (y=y+1 => y=4)
5. +     (x=x+y => x=10)


"RE: Провокационный вопрос  по C"
Отправлено anonymous , 18-Сен-02 21:38 
>Дано
>
>y=1;
>x=++y + ++y + ++y;
>
>Чему равен x ?

A compliant implementation may return 6, for example.

This is a classic case of unspecified behaviour. A c standard doesn't
dictate any particular order of evaluation between sequence points
(in your example the sequence point would be a ';'). Besides the
obvious numerical operations, your expression has also implicit
lvalue-to-rvalue conversions, which also happen in an unspecified
order.


"RE: Провокационный вопрос  по C"
Отправлено XMan , 18-Сен-02 22:05 
Ну 6 оно, пожалуй вернуть не могло, ибо ++y исключает наличие единиц в операндах. Минимум - это 9.

"RE: Провокационный вопрос  по C"
Отправлено sas , 18-Сен-02 23:11 
Hi,

Actually it can return "anything" (i mean 6 or 9 or ...) because like it was mentioned in the previous post C standard does not specify order of expression's evaluation. It is compiler implementation specific. Even operator precedence does not work  in this case.

Simple rule works ok: do not write complex expressions where object is modified more than once or modified and inspected after it.

"Important ambiguous" operators are ++, --, =, +=, -=.

Also there is a notion of the so called "sequence points" in the ANSI C standard

Conclusion: It is always better not to write ambiguous code.

Thanks
--- Sas


"RE: Провокационный вопрос  по C"
Отправлено XMan , 18-Сен-02 23:40 
Ну по идее, единствееное, что компилер может сделать, это подобная операция:
y++;
x=y+y+y

Тогда действительно плучится 6.


"RE: Провокационный вопрос  по C"
Отправлено sas , 19-Сен-02 00:55 
>Ну по идее, единствееное, что компилер может сделать, это подобная операция:
>y++;
>x=y+y+y
>
>Тогда действительно плучится 6.

Hi XMan,

Good that you found out how one of the compilers evaluate particular expression. :)

But the point is that you must not use this kind of stuff and be interesting in how  it is done by compiler developer. Because you can not be sure that your code works right being compiled with diffrent compilers.

Thanks
--- Sas


"RE: Провокационный вопрос  по C"
Отправлено XMan , 19-Сен-02 01:40 
Ну так никто ж не против - подобные конструкции кроме непоняток с компилерами и усложнения понимания кода ни к чему не приводят.
А вообще я понял так, что вопрошающего просто удивил результат. Уж незнаю, пользует он это у себя или просто посмотреть решил, что получится но вот... :))
Хотя на самом деле по всем правилам вычисления выражений действительно должно быть 6, а если пользовать специфики конструкции "++y" - должно быть 9 и раскладываться при этом в подобный (немного оптимизированный) код:

mov ax,y
inc ax
push ax
; mov y,ax
inc ax
push ax
; mov y,ax
inc ax
mov y,ax
pop dx
add ax,dx
pop dx
add ax,dx
mov x,ax

что java, похоже, и делает :))


"RE: Провокационный вопрос  по C"
Отправлено Soldier , 19-Сен-02 07:06 
>А вообще я понял так, что вопрошающего просто удивил результат.

Ну можно и так сказать. Я просто не понял с каких  gcc  выдает 10 при
x=++y + ++y + ++y   и 12 при x=++y + (++y + ++y). Про польскую запись я что-то не подумал (хотя должен был - старею, тупею :((( ...):
x=++y + (++y + ++y)  в польской записи (типа все таки знаю я что это такое ;-)) :
(x) ( (++y) ((++y) (++y) +)) + ) =
1. ++y -> y=2
2. ++y -> y=3
3. ++y -> y=4
4. (y) (y) + -> y+y=8
5. (y) (8) + -> y+8=12
6. (x) (12) = -> x=12

>Уж незнаю, пользует он это у себя
Естественно нет. Просто я недавно сварганил свой C-шный интерпретатор, в моей реализации x равен 9. Стал сравнивать результат с  другими интерпретаторами и компиляторами и нарвался вот.



"RE: Провокационный вопрос  по C"
Отправлено Аноним , 19-Сен-02 20:46 
>>А вообще я понял так, что вопрошающего просто удивил результат.
>
>Ну можно и так сказать. Я просто не понял с каких  
>gcc  выдает 10 при
>x=++y + ++y + ++y   и 12 при x=++y +
>(++y + ++y). Про польскую запись я что-то не подумал (хотя
>должен был - старею, тупею :((( ...):
> x=++y + (++y + ++y)  в польской записи (типа все
>таки знаю я что это такое ;-)) :
> (x) ( (++y) ((++y) (++y) +)) + ) =
>1. ++y -> y=2
>2. ++y -> y=3
>3. ++y -> y=4
>4. (y) (y) + -> y+y=8
>5. (y) (8) + -> y+8=12
>6. (x) (12) = -> x=12
>
>>Уж незнаю, пользует он это у себя
>Естественно нет. Просто я недавно сварганил свой C-шный интерпретатор,

Если Ваш проект более чем игрушка для себя, настоятельно рекомендую
купить копию ISO 9899, и сверяться с ним и только с ним. Это
*единственное* authoritative (как это по русски?) определение языка
C на сегодняшний день.

В нем, среди прочего, сказано (Addendum J), что повторная
модификация объекта без sequence point образует undefined behaviour
(в первом чтении было unspecified). Это значит, что в "правильной"
программе такие конструкции запрещены; генерируемый из них код может
делать все, что угодно, и претензии к компилятору не принимаются.

>в моей реализации
>x равен 9. Стал сравнивать результат с  другими интерпретаторами и
>компиляторами и нарвался вот.



"RE: Провокационный вопрос  по C"
Отправлено anonymous , 19-Сен-02 01:06 
>Hi,

>Actually it can return "anything" (i mean 6 or 9 or ...)

It is even worse. I just checked with the standard, and it does not
say "unspecified" but "undefined", meaning that a compliant compiler
is allowed to generate code which will format your hard drive or call police.

>Conclusion: It is always better not to write ambiguous code.

Agreed.

>Thanks
>--- Sas

PS Sorry for English.


"RE: Провокационный вопрос  по C"
Отправлено sas , 19-Сен-02 02:54 
>>Hi,
>
>>Actually it can return "anything" (i mean 6 or 9 or ...)
>
>It is even worse. I just checked with the standard, and it
>does not
>say "unspecified" but "undefined", meaning that a compliant compiler
>is allowed to generate code which will format your hard drive or
>call police.

:)))

>
>>Conclusion: It is always better not to write ambiguous code.
>
>Agreed.
>
>>Thanks
>>--- Sas
>
>PS Sorry for English.



"RE: Провокационный вопрос  по C"
Отправлено anonymous , 19-Сен-02 07:59 
>Дано
>
>y=1;
>x=++y + ++y + ++y;
>
>Чему равен x ?
Чтобы не задавать себе подобных вопросов надо использовать нормальный язык программирования: Ada95.


"RE: Провокационный вопрос  по C"
Отправлено Soldier , 19-Сен-02 10:42 
>>Дано
>>
>>y=1;
>>x=++y + ++y + ++y;
>>
>>Чему равен x ?
>Чтобы не задавать себе подобных вопросов надо использовать нормальный язык программирования: Ada95.
>

Че тo я не понял - вам что по-флеймить захотелось? При чем здесь Ada95?  В сабже ясно написано  - C. И по моему я ясно объяснил откуда возник данный вопрос в треде N 12. Да и задавал я его не себе, а форуму :)


Best.


"RE: Провокационный вопрос  по C"
Отправлено Cooler , 19-Сен-02 12:54 
Dobroe vremia sutok!
Ia tak podrazumevaiu, chto ti ojidal, chto ti poluchish kuchu raznih otvetov, potomu chto SAM OTVET zavisit ot COMPAILERA i edinogo otveta tut bit' ne mojet.
Obiasnaiu:
y+++y mojno interpretirovat' kak y++  +y  ili y+ ++y.  Ia nadeius' VSE ponimaiut chto eto raznie veshi. Esli net -- Sorry.
A to, chto ti tam propuski nastavil mejdu plusami, to eto nichego ne meniaet -- compailer na nih ne smotrit.
Thnx.

"RE: Провокационный вопрос  по C"
Отправлено Soldier , 19-Сен-02 13:25 
>Dobroe vremia sutok!
>Ia tak podrazumevaiu, chto ti ojidal, chto ti poluchish kuchu raznih otvetov,
>potomu chto SAM OTVET zavisit ot COMPAILERA i edinogo otveta tut
>bit' ne mojet.
>Obiasnaiu:
>y+++y mojno interpretirovat' kak y++  +y  ili y+ ++y.  
>Ia nadeius' VSE ponimaiut chto eto raznie veshi. Esli net --
>Sorry.


>A to, chto ti tam propuski nastavil mejdu plusami, to eto nichego
>ne meniaet -- compailer na nih ne smotrit.
>Thnx.

Вы бы матчасть поучили бы прежде чем чушь пороть то. В том то и дело, что y++ +y и
y+ ++y  рассматриваются совершено по разному. Если расматривать это как поток лексем то получим:
1)  id(y),++,пусто, +, id(y)
2)  id(y), +,пусто, ++,id(y)

А если этого кто то не понимает то Sorry вдвойне.

Best.


"RE: Провокационный вопрос  по C"
Отправлено someuser , 24-Сен-02 13:59 
написал однаждый Керниган книгу такую умную - Практика программирования.
И в ней написано, что такая конструкция - есть плохой стиль программирования, и то что разные компиляторы под разные оси, могут выдать разный результат :)
ps. советую почитать



"RE: Провокационный вопрос  по C"
Отправлено Soldier , 24-Сен-02 15:24 
>написал однаждый Керниган книгу такую умную - Практика программирования.
>И в ней написано, что такая конструкция - есть плохой стиль программирования,
>и то что разные компиляторы под разные оси, могут выдать разный
>результат :)
>ps. советую почитать

У-ф-ф-ф... Ну извините меня тормоза за тупой вопрос. Представьте себе,
я и без этой книги догадался, что разные компиляторы выдают разный
результат, ну а  насчет того, что такая конструкция есть плохой стиль
программирования (невероятно!!!) даже знал.

Ну а что касается самого вопроса, объясняю еще раз, более подробно, специально
для любителей давать "гениальные" советы:

Я сделал свой C-интерпретатор. Данный код был частью тестирования его работы.
Далее я стал сверять результаты с другими компиляторами и интерпретаторами.
Пока я получал в зависмости от компилера 9 или 12 меня это не удивляло, потому
что мне было абсолютно ясно как оно может получиться. Но когда gcc выдал 10,
а при перегрупировке слагаемых 12 (тут я конечно лоханулся - но с кем не бывает),
меня это поставило в тупик. И именно это побудило меня задать этот вопрос - может
еще какие сюрпризы будут.  Да  только понял  меня один  XMan.
Кстати, XMan, спасибо  тебе за подсказку - а то я от досады (что сам до этого не додумался)
забыл тебя поблагодарить сразу.

Таким образом, пока имеем только три варианта - 9,10 и 12

P.S. А кому  какие книжки читать я и сам могу  посоветовать.

Best