The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Провокационный вопрос  по C"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Провокационный вопрос  по C"
Сообщение от Soldier Искать по авторуВ закладки on 18-Сен-02, 09:55  (MSK)
Дано

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

Чему равен x ?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "RE: Провокационный вопрос  по C"
Сообщение от erg emailИскать по авторуВ закладки on 18-Сен-02, 14:42  (MSK)
>Дано
>
>y=1;
>x=++y + ++y + ++y;
>
>Чему равен x ?

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

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "RE: Провокационный вопрос  по C"
Сообщение от Soldier Искать по авторуВ закладки on 18-Сен-02, 15:57  (MSK)
>Прикинув то как это "должно быть" по моему инению "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.

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

  Рекомендовать в FAQ | Cообщить модератору | Наверх

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

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)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "RE: Провокационный вопрос  по C"
Сообщение от anonymous emailИскать по авторуВ закладки on 18-Сен-02, 21:38  (MSK)
>Дано
>
>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.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "RE: Провокационный вопрос  по C"
Сообщение от XMan emailИскать по авторуВ закладки on 18-Сен-02, 22:05  (MSK)
Ну 6 оно, пожалуй вернуть не могло, ибо ++y исключает наличие единиц в операндах. Минимум - это 9.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "RE: Провокационный вопрос  по C"
Сообщение от sas emailИскать по авторуВ закладки on 18-Сен-02, 23:11  (MSK)
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

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "RE: Провокационный вопрос  по C"
Сообщение от XMan emailИскать по авторуВ закладки on 18-Сен-02, 23:40  (MSK)
Ну по идее, единствееное, что компилер может сделать, это подобная операция:
y++;
x=y+y+y

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

  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "RE: Провокационный вопрос  по C"
Сообщение от sas emailИскать по авторуВ закладки on 19-Сен-02, 00:55  (MSK)
>Ну по идее, единствееное, что компилер может сделать, это подобная операция:
>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

  Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "RE: Провокационный вопрос  по C"
Сообщение от XMan emailИскать по авторуВ закладки on 19-Сен-02, 01:40  (MSK)
Ну так никто ж не против - подобные конструкции кроме непоняток с компилерами и усложнения понимания кода ни к чему не приводят.
А вообще я понял так, что вопрошающего просто удивил результат. Уж незнаю, пользует он это у себя или просто посмотреть решил, что получится но вот... :))
Хотя на самом деле по всем правилам вычисления выражений действительно должно быть 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, похоже, и делает :))

  Рекомендовать в FAQ | Cообщить модератору | Наверх

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

Ну можно и так сказать. Я просто не понял с каких  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. Стал сравнивать результат с  другими интерпретаторами и компиляторами и нарвался вот.


  Рекомендовать в FAQ | Cообщить модератору | Наверх

17. "RE: Провокационный вопрос  по C"
Сообщение от Аноним emailИскать по авторуВ закладки on 19-Сен-02, 20:46  (MSK)
>>А вообще я понял так, что вопрошающего просто удивил результат.
>
>Ну можно и так сказать. Я просто не понял с каких  
>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. Стал сравнивать результат с  другими интерпретаторами и
>компиляторами и нарвался вот.


  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "RE: Провокационный вопрос  по C"
Сообщение от anonymous emailИскать по авторуВ закладки on 19-Сен-02, 01:06  (MSK)
>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.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "RE: Провокационный вопрос  по C"
Сообщение от sas emailИскать по авторуВ закладки on 19-Сен-02, 02:54  (MSK)
>>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.


  Рекомендовать в FAQ | Cообщить модератору | Наверх

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

  Рекомендовать в FAQ | Cообщить модератору | Наверх

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

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


Best.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

15. "RE: Провокационный вопрос  по C"
Сообщение от Cooler Искать по авторуВ закладки on 19-Сен-02, 12:54  (MSK)
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.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

16. "RE: Провокационный вопрос  по C"
Сообщение от Soldier Искать по авторуВ закладки on 19-Сен-02, 13:25  (MSK)
>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.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

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


  Рекомендовать в FAQ | Cообщить модератору | Наверх

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

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

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

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

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

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

Best

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру