The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Провокационный вопрос  по C, !*! Soldier, 18-Сен-02, 09:55  [смотреть все]
Дано

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

Чему равен x ?


  • RE: Провокационный вопрос  по C, !*! erg, 14:42 , 18-Сен-02 (1)
    >Дано
    >
    >y=1;
    >x=++y + ++y + ++y;
    >
    >Чему равен x ?

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

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

      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, 21:38 , 18-Сен-02 (4)
    >Дано
    >
    >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, 22:05 , 18-Сен-02 (5)
      Ну 6 оно, пожалуй вернуть не могло, ибо ++y исключает наличие единиц в операндах. Минимум - это 9.

      • RE: Провокационный вопрос  по C, !*! sas, 23:11 , 18-Сен-02 (6)
        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, 23:40 , 18-Сен-02 (7)
          Ну по идее, единствееное, что компилер может сделать, это подобная операция:
          y++;
          x=y+y+y

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

          • RE: Провокационный вопрос  по C, !*! sas, 00:55 , 19-Сен-02 (8)
            >Ну по идее, единствееное, что компилер может сделать, это подобная операция:
            >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, 01:40 , 19-Сен-02 (10)
              Ну так никто ж не против - подобные конструкции кроме непоняток с компилерами и усложнения понимания кода ни к чему не приводят.
              А вообще я понял так, что вопрошающего просто удивил результат. Уж незнаю, пользует он это у себя или просто посмотреть решил, что получится но вот... :))
              Хотя на самом деле по всем правилам вычисления выражений действительно должно быть 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, 07:06 , 19-Сен-02 (12)
                >А вообще я понял так, что вопрошающего просто удивил результат.

                Ну можно и так сказать. Я просто не понял с каких  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, !*! Аноним, 20:46 , 19-Сен-02 (17)
                  >>А вообще я понял так, что вопрошающего просто удивил результат.
                  >
                  >Ну можно и так сказать. Я просто не понял с каких  
                  >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, 01:06 , 19-Сен-02 (9)
          >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, 02:54 , 19-Сен-02 (11)
            >>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, 07:59 , 19-Сен-02 (13)
    >Дано
    >
    >y=1;
    >x=++y + ++y + ++y;
    >
    >Чему равен x ?
    Чтобы не задавать себе подобных вопросов надо использовать нормальный язык программирования: Ada95.


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

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


      Best.


  • RE: Провокационный вопрос  по C, !*! Cooler, 12:54 , 19-Сен-02 (15)
    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, 13:25 , 19-Сен-02 (16)
      >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, 13:59 , 24-Сен-02 (18)
    написал однаждый Керниган книгу такую умную - Практика программирования.
    И в ней написано, что такая конструкция - есть плохой стиль программирования, и то что разные компиляторы под разные оси, могут выдать разный результат :)
    ps. советую почитать

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

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

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

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

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

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

      Best




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

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