1. Java / Говнокод #3535

    +89

    1. 1
    pp = pp++;

    Что хотел сказать автор?...

    Запостил: tinynick, 22 Июня 2010

    Комментарии (97) RSS

    • xD, наверное nop, то есть ничего
      Ответить
      • лучше бы автор сказал что-нибудь такое
        pp += pp++ + ++pp;
        Ответить
        • 0
          2
          8
          26
          80
          242
          728
          2186
          6560
          19682
          59048
          ...
          Эту бомбу тогда вычислили бы быстро ><
          Ответить
    • беспощадно
      Ответить
    • показать все, что скрытоон хотел сказать
      pp = pp;
      pp++;

      бред.
      Ответить
      • в яве ваш код будет работать иначе чем то что сказал автор
        не знаю как плюсах
        смахивает на UB
        Ответить
        • показать все, что скрытодействительно :)

          C# даёт 10 :)

          L_0000: nop 
              L_0001: ldc.i4.s 10
              L_0003: stloc.0 
              L_0004: ldloc.0 
              L_0005: dup 
              L_0006: ldc.i4.1 
              L_0007: add 
              L_0008: stloc.0 
              L_0009: stloc.0 
              L_000a: ret
          Ответить
          • блин, что за херню вы постите?
            причем тут
            {pp++;
            pp = pp;
            }
            pp = pp++; // в яве, шарпе, js точно будет pp

            а вот в c/c++ это как компилер решит, думаю т.к. под pp заведется одна ячейка, то результатом будет pp+1, но вообще хз
            Ответить
            • показать все, что скрыто
              int pp = 10;
                  pp = pp++;
                  
                  printf("%d\n", pp);


              gcc/o1 тоже даёт 10.

              по мне так как-то глупо. им там чо, компиляторы в лом делать?
              Ответить
              • у Уебкилла разрыв шаблона,
                >>>по мне так как-то глупо
                а как по мне нормально,
                интересно как оно на MS VC++ (там вроде 11 должно быть)
                и в похапе (там вроде 10)?

                кстати зачем херню редактировать - пусть бы все лулзы ловили, стыдно стало?
                а потом еще "че вы меня минусуете?"
                Ответить
                • кстати в питоне что
                  i=++i;
                  что
                  i=i++;
                  будет i )))
                  и в раби кажись тоже ))
                  Ответить
                • В PHP как и ожидалось:
                  -bash-4.0$ php -r "\$p = 10; \$p = \$p++; echo \$p;"
                  10
                  Ответить
                • показать все, что скрыто> кстати зачем херню редактировать - пусть бы все лулзы ловили, стыдно стало?

                  нет, я нашёл ответ на свои вопросы.
                  всё равно мне непонятна логика компиляторостроителей. наверное, этот прикол упирается глубоко в древность, когда в компиляторах экономили на всём. вписать пару строчек - чтобы поведение было более интуитивным ("p = p++;" == "p = p; p++;") - раз плюнуть.
                  а тут, получается, код зависит от поведения стека нижлежащей платформы. дёшево, ламерски.
                  Ответить
                  • ув. Уебкилл вас послушать создатели всех известных компилеров - дешевые ламера (о раби и питоне не будем, в них нет инкреметов i++), а вы нашли удивительно простое и универсальное решение.
                    Объясню развернуто
                    Но на самом деле все компилеры (пока не знаю о MS VC++) подчиняются строгой логике и стандартам.
                    для инкремента создается отдельная переменная (в отдельной ячейке памяти или регистре), согласно приоритету операций т.к. это постинкремент сначала выполняется присваивание.
                    i=i
                    после этого выполняется инкремент отдельно созданной переменной
                    убедится в этом можно даже прочитав тот кусок IL-asma, который вы запостили выше

                    если у нас выражение
                    i=++i; то инкремент выполняется ДО, это не то что логично, а понятно даже кэпу

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

                    но вот низкоуровневые c/c++ могут иметь хитрые оптимизаторы и сейвануть оба i в один регистр, тогда получаем i+1, думаю gcc на при некоторых выставленых оптимизациях может именно так поступить, а MS вроде так и поступает, именно по этому я не уверен как оно будет работать.
                    Ответить
                    • показать все, что скрытоя знаю, что они следуют стандарту (который говорит, что поведение неопределено).

                      и я знаю, как там внутри происходит в стеке.

                      однако, стек - это низкоуровневая вещь, и высокоуровневые языки от неё зависеть, имхо, не должны. я вообще об этом задумываться не должен.

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

                      так вот, учесть "интуитивность" здесь не так сложно - небольшое правило для анализатора, чтобы развернул выражение несколько иначе.

                      так никто не делает, не потому что они ламера, а потому что это мало кому нужно, ибо "p = p++" само по себе бессмысленно и/или говнокод.
                      Ответить
                      • А если на ноль разделить, что должно быть? А если розетку лизнуть?
                        Если интуитивно, то нормальный компилятор должен выдать ошибку и ткнуть носом.
                        Ответить
                        • показать все, что скрытов каком месте это ошибка? с точки зрения языка, не какого-то там ебаного стека, которого может и не быть, это не ошибка. а деление на ноль запрещено (ну почти) математически
                          если розетку лизнуть - определено, что будет )
                          Ответить
                      • > они следуют стандарту (который говорит, что поведение неопределено)
                        Извиняюсь, что влезаю тут со своим похапе, но в нём всё очень даже определено...
                        http://www.php.net/manual/en/language.operators.precedence.php
                        Что выше, то и вычисляется в первую очередь. И смысл выражения из этого очень даже понятен. Постинкремент вычисляется первым, увеличивает значение переменной, но возвращает старое. Это старое поступает на оператор присваивания, который затирает увеличенное значение, заменяя его обратно на старое. Логика есть, её просто надо включить. Что касается интуитивности - разве разработчики компиляторов не в своём праве, если хотят отойти от неё в пользу строгой логичности выполнения? Разве не присутствует в этом решении такой плюс, как отсутствие необходимости разжёвывать это интуитивное исключение в мануале и терпеть толпу ламеров, которые про него не прочитают и споткнутся? Всякая интуитивность вроде предлагаемого исключения на конкретную узкую ситуацию - это костыль, а костыли в стратегическом плане ничего, кроме проблем, обычно не приносят. Это я в том числе как похапешник говорю. Т_Т
                        Ответить
                        • показать все, что скрыто> Постинкремент вычисляется первым, увеличивает значение переменной, но возвращает старое

                          > но возвращает старое

                          > Логика есть

                          где здесь логика, которую я должен включить? на уровне языка здесь логики нет. на уровне реализации типа стека - может быть, только тогда я не секу pointa использования таких "высокоуровневых" языков. "p++" это ведь не (p + 1), операция должна писать прямо в переменную (и без разницы, когда это случается), при чём тут стек.
                          Ответить
                          • показать все, что скрытоя понимаю их логику, но по-моему можно было умнее сделать, т.е рассматривать приравнивание в таких случаях как нечто единое, чтобы ++ случался уже после всего, а не где-то между стеком и жопой.
                            Ответить
                            • > на уровне языка здесь логики нет
                              По-моему, кто-то не выучил матчасть.
                              > операция должна писать прямо в переменную (и без разницы, когда это случается)
                              > чтобы ++ случался уже после всего, а не где-то между стеком и жопой.
                              Операция присваивания - такая же часть выражения, как и любая другая, и момент её выполнения (как и любой другой, опять же) строго определён приоритетом операций. Этого совершенно достаточно для понимания, как вычисляется то или иное выражение. Другое дело, что в разных языках то ли таблица приоритетов немного разная, то ли компиляторы бажные и через пень-колоду следуют ей при обработке операций, которые мы тут мусолим.
                              Ответить
    • pp = 10; pp = pp + pp++;
      Результат в C# 20, в gcc 21. При перестановке слагаемых в обоих 21.
      pp = 10; pp = pp + ++pp;
      Результат в C# 21, в gcc 22. При перестановке слагаемых в обоих 22.
      pp = 10; pp = pp++ + pp++;
      Результат в C# 21, в gcc 22.
      pp = 10; pp = ++pp + ++pp;
      Результат в C# 23, в gcc 24.
      В других компиляторах мне и проверять страшно.
      Ответить
      • показать все, что скрытоот перестановки мест слагаемых сумма всё-таки меняется... в школе лгали...
        Ответить
        • А может быть авторы C# в школе не учились? В gcc сумма не меняется.
          Ответить
        • А вот ещё прикол:
          pp = 10; pp = pp-- + pp++;
          Результат в C# 19
          pp = 10; pp = pp++ + pp--;
          Результат в C# 21
          В gcc оба варианта 20.
          Замена постинкремента и постдекремента на преинкремент и предекремент в данном примере не меняет результат.
          Ответить
          • показать все, что скрытоТы в MS. NET проверял? В моно такие же цифры. Молодцы, совместимость высоко держат.
            Ответить
            • Да. Значит, код всё-таки совместим!
              Ответить
            • А в javascript ещё веселее. Примеры с одним инкрементом работают как в gcc, примеры с двумя инкрементами/декрементами — как в C#.
              Ответить
              • Да уж, блин, чем больше реализаций перебираем, тем больше лулзов...
                Ответить
                • >>>pp = 10; pp = ++pp + ++pp;
                  >>>Результат в C# 23, в gcc 24.
                  а я о чем во второй посте говорил??

                  а вы MS VC++, его попробуйте ))
                  Ответить
              • вы неправы у меня ява-скрипт работает идентично шарпу и яве, или может тут еще от браузера зависит ))))))
                Ответить
                • >>>А в javascript ещё веселее. Примеры с одним инкрементом работают как в gcc, примеры двумя как в C#.
                  UPD. проверил в Мозилле, Хроме, Опере, ИЕ.
                  везде результат идентичный шарпу и яве
                  Ответить
                  • Сейчас перепроверил. Действительно, результат идентичный. Что-то я напутал при прошлой проверке.
                    Ответить
                    • я всегда знал, что ява, шарп и js работают в этом плане абсолютно одинаково, что не может не радовать особенно если сравнить С/С++ компилерами
                      Ответить
          • try in gcc this please
            i=0;
            (++i + ++i + ++i)
            а то у меня по рукой ниче нету чтоб проверить
            Ответить
            • кстати тут подтвердилось что MS VC++ на i=i++; выдает
              i
              что впрочем логично
              Ответить
              • Хм, проверил в VS 2005. i = i++; выдаёт i+1
                Ответить
                • AAAA!!!!!1111
                  я знал, я знал, что какой-то из MS VC++ компилит так.
                  все у них не как у людей
                  Ответить
                  • Зато такие выражения можно применять для извращённой проверки версии компилятора. Помните, как раньше тип процессора определяли? В 8086 команда PUSH SP сначала декременировала SP, потом клала новое значение в стек. В более новых процессорах в стек кладётся старое значение SP, а уже потом выполняется декремент.
                    Ответить
                    • дефайны же есть для проверки версии компилятора, в гну это например __GNUC__, __GNUC_MINOR__ __GNUC_PATCHLEVEL__.. бредовое предлоеэжиение
                      Ответить
                      • Дефайны передефайнить можно.
                        Ответить
                        • а ещё можно компилятор удалить в корзину. и чё?)
                          Ответить
                          • А то, что include-файлы иногда слишком много на себя берут и переопределяют макросы, поэтому дефайнам не всегда верить можно.
                            Зря что ли autoconf генерирует короткие программы для теста компиляторов?
                            Ответить
                            • кто в здравом уме и памяти будет переопределить макросы, идентифицирующие компилятор? омг.

                              у тебя какое-то потакание говнокоду, я посмотрю (
                              Ответить
            • кстати дошли руки до машины с компилерами
              i=0;
              (++i + ++i + ++i)
              GCC 4.34 -o1 = 7 какого?????
              javascript: i=0;alert((++i + ++i + ++i)); = 6
              Java, С# тоже должны 6
              а вот MS 2005 по идее должен выдать 9 )))))
              Ответить
            • Докладываю. Если использовать (++i + ++i + ++i) в правой части (например, в printf), то gcc выдаёт 7 (пробовал разные ключи оптимизации, результат не меняется).
              C# возвращает 6 (и javascript тоже).
              Ответить
              • блин а я что чуть выше запостил??
                >>> gcc выдаёт 7
                кто возьмется объснить?

                эта на MS VC++ 2005 испробуйте (++i + ++i + ++i)
                Ответить
                • >>> блин а я что чуть выше запостил??
                  На время публикации посмотрите. Почти одновременно. Я не сразу «Отправить» нажал.
                  Девятка из-за тройного преинкремента и оптимизации 3*i ?
                  Кстати, gcc -O2 тупо возвращает константу в ответе, то есть вычисления ещё на стадии компиляции. А без оптимизации генерирует истинный говнокод (синтаксис Intel мне более понятен, чем AT&T):
                  mov	DWORD PTR [ebp-4], 0 ; i = 0;
                  	lea	eax, [ebp-4]
                  	inc	DWORD PTR [eax]         ; ++i; теперь i = 1
                  	lea	eax, [ebp-4]                    ; зачем? в eax  уже адрес переменной
                  	inc	DWORD PTR [eax]          ; ++i; теперь i = 2
                  	mov	eax, DWORD PTR [ebp-4] ; eax = i; 
                  	mov	edx, DWORD PTR [ebp-4]  ; edx = i; 
                  	add	edx, eax                               ; edx = edx + eax; теперь edx = i + i, то есть 4
                  	lea	eax, [ebp-4]
                  	inc	DWORD PTR [eax]               ; ++i; Yes! теперь i = 3
                  	mov	eax, edx                                 ; в edx была та самая четвёрка
                  	add	eax, DWORD PTR [ebp-4] ; сложим и получим 7

                  Итак, в сумме первые два слагаемых - это результат двух инкрементов i (оптимизация, блин), а третье слагаемое — после третьего инкремента.
                  Ответить
                  • Короче, если бы mov eax, DWORD PTR [ebp-4] было двумя строками выше, то было бы 6 (Вру, ещё названия регистров поменять надо).
                    Ответить
                  • >>>Почти одновременно.
                    бывает и такое ))

                    >>>то есть вычисления ещё на стадии компиляции.
                    причем неверные xD

                    из дизассемблинга ясно почему gcc неверно считает (выдает на 1 больший резулт)
                    (++i + ++i )=4
                    (++i + ++i + ++i )=7
                    (++i + ++i + ++i + ++i )=11
                    итд

                    оно создает копию первого ++i в eax позже чем надо (как уже сказано это надо делать 2-мя строками ранее), а с остальными работает нормально
                    походу баг
                    Ответить
                    • Сортирует операции для оптимизации использования регистров. То есть это не логика компилятора, а логика кодогенератора. Надо проверить, что gcc генерирует под другие процессоры, например RISC, у которых регистров куча, или наоборот для стековых процессоров.
                      А ещё попробовать разбавить формулу другими выражениями, чтобы оптимизация споткнулась.
                      Ответить
                      • не ну на простом выражении типа ++i+ ++i выдавать херню это недопустимо.
                        или ему 2-х регистров мало?
                        так и на этапе компиляции неправильно считает.
                        может это фича gcc? /-:
                        Ответить
                        • Ещё крупно повезло, что результат, посчитанный на этапе компиляции, совпадает с результатом этапа выполнения. Была злая шутка с вещественными типами в Турбо-паскале, когда не совпадало.
                          Ответить
                        • Как я уже написал, для того, чтобы перенести mov на две строки вверх, надо сменить регистр, например, на ebx или ecx.
                          gcc генерирует код в два этапа. Если я правильно понял, что там написано в документации, то сначала генерируется код на языке RTL (register translation language) под виртуальный процессор, у которого количество и назначение регистров отличается от реального. Потом gcc конвертирует RTL в ассемблерный код для конкретного процессора. Даже если нам регистров хватает, их может не хватить RTL, поскольку он эмулирует весьма искусственную машину.
                          Если на сайте есть компиляторостроители, поправьте меня.
                          Ответить
                • На старом MSVC действительно девятка.
                  Ответить
                  • А вот листинг:
                    inc	DWORD PTR _i$[ebp]
                    	inc	DWORD PTR _i$[ebp]
                    	inc	DWORD PTR _i$[ebp]
                    	mov	eax, DWORD PTR _i$[ebp]
                    	add	eax, DWORD PTR _i$[ebp]
                    	add	eax, DWORD PTR _i$[ebp]

                    Все инкременты вычисляются ДО вычисления формулы.
                    Ответить
                    • да именно из-за этого MS VC i=i++;считает как i+1
                      и тут выдает 9.
                      он сейвит все i в одну переменную.
                      впрочем я говорил об этом еще в начале треда.

                      >>>Borland C возвращает (сюрприз!) 6, как в яве и в шарпе.
                      хм, а я его всегда говном считал
                      Ответить
                      • К компиляторам, как и к любому софту, обычно предвзятое отношение. Одни боготворят Борланд, другие проклинают. По мне у них вполне годные компиляторы, хотя багов в runtime-библиотеках хватает. А репутация подмочена из-за говнокодеров, пишущих на Дельфи и Билдере. Кстати, в дельфях никто не заставляет использовать визуальные конструкторы, можно и в текстовом редакторе код набирать. Да и код генерируется достаточно хороший. Если код тяжёлый или медленный — это кусок из неотёсанных runtime-библиотек.

                        Отвлёкся от темы. Результат Борланда, совпадающий с явой и шарпом, меня тоже удивил.
                        Ответить
                • А формулу с постинкрементом проверял кто-нибудь?
                  (i++ + i++ + i++)
                  В gcc получается ноль, потому что он сначала складывает, потом выполняет инкремент (то есть i=3, а правая часть нулю).
                  MSVC на этот раз совпадает с шарпом: тройка в ответе. Листинг MSVC:
                  mov	eax, DWORD PTR _i$[ebp]
                  	mov	DWORD PTR -8+[ebp], eax ; запоминаем i (ноль) в локальной переменной
                  	inc	DWORD PTR _i$[ebp] ; ++i; теперь i =1 
                  	mov	eax, DWORD PTR _i$[ebp]
                  	mov	DWORD PTR -12+[ebp], eax ; запоминаем i (единицу) в локальной переменной
                  	inc	DWORD PTR _i$[ebp] ; ++i; теперь i=2
                  	mov	eax, DWORD PTR _i$[ebp]
                  	mov	DWORD PTR -16+[ebp], eax ; запоминаем i (двойку) в локальной переменной
                  	inc	DWORD PTR _i$[ebp] ; ++i; теперь i=3
                  	mov	eax, DWORD PTR -8+[ebp] ; нолик
                  	add	eax, DWORD PTR -12+[ebp] ; прибавляем единицу
                  	add	eax, DWORD PTR -16+[ebp] ; прибавляем двойку

                  На этот раз всё чётко. Разный приоритет операций. gcc выполняет постинкремент после вычисления формулы, а шарп и MSVC — по ходу вычисления.
                  Ответить
            • Проверил другие компиляторы.
              Watcom C возвращает 7, как и gcc.
              Borland C возвращает (сюрприз!) 6, как в яве и в шарпе.
              В обоих случаях 16-битный и 32-битный компиляторы вычисляют одинаково.
              Ответить
              • заебошь статью на хакеп точку ру, чё )
                Ответить
                • Да тут непосредственно сам этот пост за исследование сойдёт. Интересная инфа.
                  Ответить
                • Хорошая мысль!
                  Ответить
        • от смены компилятора сумма меняется, а все дело в приоритете операций.
          то есть все зависит от условленого порядка операций и в этом ничего сложного нет

          кстати ява будет себя вести точно как и шарп и тому есть веские причины
          в яве и шарпе приоритеты ++ и сложения одинаковы в c/c++
          у инкремента выше

          вот к примеру
          pp = 10; pp = pp + pp++;

          потому pp=10 + 10, а потом уже инкремент
          при перестановке сначала инкремент (возвратит 10), потом сложение с уже увеличенным до 11
          то есть
          pp=10+11

          >>>pp = 10; pp = pp + ++pp;
          10+11 //т.к. прединкремент

          ++pp+pp
          11+11 //т.к. прединкремент уже изменил значение ячейки

          p = ++pp + ++pp;// тут вообще элементарно
          11+12

          в gcc как я понимаю более приоритетные инкременты
          потому
          >>pp = pp + pp++;
          сначала выполнится инкремент, но возвратит 10, но pp уже изменилось а потом выполнит сложение
          11 + 10, от перестановки сумма не меняется, поскольку инкремент выполняется раньше

          >>>pp = pp + ++pp;
          тут приоритет ++pp выше и он сразу увеличит значение pp на 1 и вернет 11
          а потом сложение
          11+11=22
          итд...

          >>А в javascript ещё веселее.
          ЗЫ по поводу js я всегда думал он работает как ява и шарп, надо будет глянуть мануал
          Ответить
          • Убедительное доказательство, что у C, C++, C#, Java, JavaScript и т. п. только синтаксис похож, а семантика в корне различается, что затрудняет портирование программ с одного языка на другой, чтобы программистам жизнь мёдом не казалась.
            Ответить
    • Тут несколько вариантов:
      1) Автор Паскалист
      2) рр это объект класса и ++ перегружен на выполнение какого-нибудь извращенского действия
      Ответить
      • в паскале нет i++, в паскале inc(i), так что первое мимо
        Ответить
        • Именно. inc(i) в Паскале не возвращает значения, поэтому не позволяет сооружать такие конструкции с побочным эффектом. В Си и в подобных языках ещё оператор присвоения можно использовать в любых выражениях (в rvalue), а в Паскале так нельзя. Си иногда называют write-only языком, потому что сразу понять, что делает код, порой невозможно.
          Ответить
          • >inc(i) в Паскале не возвращает значения, поэтому не позволяет сооружать такие конструкции с побочным эффектом
            inc(i) - без побочных эффектов???

            >Си иногда называют write-only языком
            У вас галлюцинации... Такое говорили про форт, причем исключительно неасиляторы.
            Ответить
            • Какие нафиг побочные эффекты, если в Паскале inc — это процедура, а не функция, то есть аналог void в сях, потому что ничего не возвращает. Вы наверное путаете inc с succ, которая возвращает увеличенное значение, но succ аргумент не изменяет, поэтому тоже никаких побочных эффектов.
              Ответить
              • > Какие нафиг побочные эффекты, если в Паскале inc — это процедура, а не функция, то есть аналог void в сях, потому что ничего не возвращает

                эммм, какая разница, процедура это или функция. если изменяется состояние после вызова - то это побочный эффект. inc только и делает, что побочный эффект генерирует.

                вот например процедура без побочного эффекта:

                void f() { }

                :)
                Ответить
                • Ну тогда если void-функция хоть что-то делает, то это побочный эффект. А где тогда основной?
                  Ответить
                  • это тупо вопрос терминологии, не нравится слово "побочный" - выдумай что-то более слух ласкающее

                    по сути процедура это та же функция, только возвращающая "ничто".
                    Ответить
    • Пытаюсь прийти в себя. Код из 10 символов (в принципе хватило бы и шести: p=p++;) породил целую гору комментариев. Я понял, что в программировании понимаю чуть меньше, чем нихрена.

      Предлагаю всех, кто использует инкременты, декременты и присвоения в правой части, жечь на костре.
      Ответить
      • Всё правильно, не стоит воспринимать постинкремент как некую данность, типа закона физики.
        Дотошное понимание такой хрени нисколько не характеризует программиста :)
        Ответить
        • [QUOTE] Дотошное понимание такой хрени нисколько не характеризует программиста :)[/QUOTE]
          ну надо хотя бы иметь представление как будет выполнятся твой код
          потому тот язык на котором пишешь необходимо знать как можно дотошнее.

          [QUOTE] Я понял, что в программировании понимаю чуть меньше, чем нихрена.[/QUOTE]
          чем больше знаний, тем больше понимаешь насколько их мало
          Ответить
          • как-то херово BBcode работает
            codecoce

            [PHP]phphph[/PHP]
            Ответить
          • > ну надо хотя бы иметь представление как будет выполнятся твой код

            "p = p++" это бессмысленный говнокод. Зачем его понимать?
            Ответить
            • да но этот бессмысленный говнокод породил интересную тему и дальше разговор перешел на выражения типа ++i+ ++i, а инкремент переменной и ее дальнейшее использование в одном выражении - вполне возможный вариант.
              и тут нужно четко знать что произойдет.
              Ответить
      • a[i]=i++;
        а как вам такое? ))
        Ответить
    • судя по дискуссиям, выражение пре и пост инкремента и декремента должно результироваться в войд, что бы не смущать программеров
      Ответить
      • Пре- и постинкременты суть маленькие кусочки чистого зла.
        И зло в том, что
        1) это побочный эффект,
        2) это побочный эффект с недетерминированным временем срабатывания
        3) это экономит небольшое количество байтов в тексте программы, из-за чего их всё любят несмотря на первые 2 причины.

        Наверное 3-й пункт есть проявление Великой Лени выражающейся в стремлении печатать как можно меньше букв.
        Ответить
      • Кстати, достаточно их вообще удалить из всех языков.
        Выражение pp += 1 вполне может заменить всё, где могут понадобиться пре/постинкременты. Классический пример с
        while(*p++=*q++);
        можно переписать как
        while(*p = *q) { p += 1; q += 1; }
        что не столь изящно, но намного чётче сформулировано.
        Ответить
    • Теперь я ещё более полюбил конструкцию i += 1 и считаю, что она должна быть стейтментом (или Unit), ибо нехрен.
      Ответить
      • А i++ в виде стейтмента чем плох?
        Ответить
        • лишняя сущность
          Special cases are not special enough
          ++ - конкатенация списков
          Ответить
        • тут, скорее, ++i аналогичен (i += 1)
          весь батхёрт из пустого места - в write-only языке, из исторических причин, или в угоду ленивым разработчикам оптимизаторов, просто зафиксировали, что это UB использовать *инкремент рядом с доступом к переменной - развлекайтесь, как хотите, дети мои, а в read-write-execute-profit языках изначально отделили мух от котлет, рассказав в каком конкретно направлении и порядке какие операции выполняются
          эволюция-с
          Ответить
      • Ром, а как её можно не любить-то? Тут джвух мнений быть не может.
        Инкременты же сахарок. Для экономии одного символа.
        >и считаю, что она должна быть стейтментом
        Главное - убрать побочный эффект, да.
        Убрать и не пущать, ибо не стоит оно того гемора и майндфака.
        Ответить
    • [color=black]UD[/color]
      Ответить
    • - Так вот что я Вам скажу! Вы ничего не понимаете! Я не знаю, как там у вас в БДСМ. Но, похоже, там всё неправильно у вас!
      Ответить

    Добавить комментарий