На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> баги в операторе ++???
    есть код { int x = 0; x = x++; } бред, конечно. Но возникает вопрос: чему должен быть равен x? По идее - 0, в самом деле имеем: выполняется x++, и возвращает значение x до инкремента, а потом выполняется оператор =, присваивающий результат x++ переменной x. Понятно, что результат x++, даст 0. Но, о чудо! x == 1! Как такое может быть???
    Испробовал VC++ 7.0 и gcc. Результат описан выше :(
    Попробовал написать класс реализующий методы инта: = и ++(int). Попробовал этот-же код с экземпляром этого класса, в результате, как и ожидалось x == 0.
    Либо мир сошел с ума, либо я. Люди помогите!
      x=x++ <=> x=x=x+1 =>x=x+1
      Комментарии излишни
        Ну, сначала присвоение потом инкрементирование - все правильно. Обе операции ведь над одним оперндом.
          А откомпилировав и запустив вот ето:
          ExpandedWrap disabled
            int main()
            {
                int x = 0, y = 0;
                x = y = x++;
                printf("%d, %d", x, y);
            }

          тоже скажете, что все правильно ;)
            Получается 1 0
            1) выполняется присвоения (x = y = 0)
            2) выполняется инкремент (x = 1)

            IMHO нет никакого бага.
              Тут не однозначность, результат зависит от компилятора
                А на каком компиляторе это не так, как я привел?
                Я пользовался g++ 2.95.4

                IMHO здесь все по стандарту.
                  в том то и дело что неодначность по стандарту, я как раз читал это в книге где приводился пример неодназчности языка С. А компиляторов много.
                    В стандарте это называется behavior is unspecified
                    Сообщение отредактировано: trainer -
                      Цитата lunc @ 13.02.04, 19:23
                      Ну, сначала присвоение потом инкрементирование - все правильно. Обе операции ведь над одним оперндом.

                      Посмотри Страуструпа, или MSDN: оператор постинкремента имеет такой-же приоритет как и ->, например. Оператор преинкремента имеет такой-же приоритет как sizeof. Это стандарт. Вопросы к Страуструпу почему так.
                      Если-бы было так как ты говоришь, то перегруженный класс должен был-бы сработать так-же, но он сработал именно так как написано в стандарте, т.е. x++ сначала, а уж присвоение - потом. Спорить тут не о чем. Есть сомнения - загляни в старину Струпа - там все доходчего разъяснено.
                      Короче, со стандартным типом при дизассемблировании видно, что порядок выполнения операторов нарушен. Сначала выполняется присвоение, а уж потом - постинкремент. Это, простите, баг.
                        Когла я говорил про последовательность, я не имел ввиду приоритет, а последовательность команд.

                        Страуструп 6.2.5 (3-е издание):
                        Цитата

                        Например, y = x++ эквивалентно y=(t=x, x+=1, t)


                        О последовательности операций в выражениях с инкрементами там ничего не говорится (ну, по крайней мере я не нашел, если есть - ткните, плз). В Лафоре довольно конкретно говорится, что постфиксный инкремент в выражениях всегда выполняется последним. Всегда так было, и выражение x = x++ - не исключение.

                        Например,
                        y = 2 * x++;
                        выглядит как:
                        Цитата

                        mov eax, [ebp-0x34]
                        add eax, eax
                        mov [ebp-0x38, eax]
                        inc dword ptr [ebp-0x34]


                        Точно так же и x = x++;
                        Цитата

                        mov eax, [ebp-0x34]
                        mov [ebp-0x38, eax]
                        inc dword ptr [ebp-0x34]


                        Пробовал компиляторы Borland и gcc - результат один. Если в каком-то компиляторе это не так, то в каком?
                        Сообщение отредактировано: lunc -
                          x=x++; с точки рения логики неодназчен в 3.1 борланд С++ x не меняется как в других компилятарах я уже не писал подобное.
                            Цитата lunc @ 15.02.04, 03:32
                            Когла я говорил про последовательность, я не имел ввиду приоритет, а последовательность команд.

                            А что такое "последовательность", по твоему? И зачем тогда нужен приоритет операции? Как раз по приоритетам команды в выражении и разбираются. Если в выходной последовательности порядок команд не соответствует приоритетам операций во входном выражении, всегда считалось что компиляция проведена с ошибками.
                              В Страустропе сказано, что результат постфиксного инкремента - значение операнда. После того, как результат помечен осуществяется инкрементирование. Итого имеем 2 операции - присвоение (пометка операнда) и инкрементирование.

                              Цитата

                              По идее - 0, в самом деле имеем: выполняется x++, и возвращает значение x до инкремента, а потом выполняется оператор =, присваивающий результат x++ переменной x


                              Здесь три операции (что видно и из фссемблерного кода), а не две. Приоритет "++" выше "=". Получаем следующую последовательность: пометка текущего значения, присвоение и инкрементирование.
                              Вопрос только в том, где считать, что "++" закончен и на какую часть операции инкрементирования распростараняется правило приоритета.
                              Поэтому на практике предполагают, что приоритет инкремента завист от его типа - постфиксный или префиксный.
                              1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0321 ]   [ 15 queries used ]   [ Generated: 14.05.24, 22:48 GMT ]