1. C++ / Говнокод #19061

    +4

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    typedef std::map<std::string, WORD> Values;
    
    struct Less {
    	bool operator()(Values::value_type const& left
    	, Values::value_type const& right) const {
    	   if (right.second == TEMPERATURE_UNKNOWN 
    		  || left.second == TEMPERATURE_UNKNOWN) {
    			 return false;
    	   }
    	   short const signed_left = *reinterpret_cast<short const*>(&left.second);
    	   short const signed_right = *reinterpret_cast<short const*>(&right.second);
    	   bool const result = signed_left < signed_right;
    	   return result;
    	}
    };

    Строки 10 и 11.
    20+ опыта в С++ у чувачка.

    Запостил: blackhearted, 21 Ноября 2015

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

    • Тут гораздо больше отжигают 6-8 строки, из-за которых TEMPERATURE_UNKNOWN будет равна любому другому значению...
      Ответить
      • Только из танка, поясните мысль
        Ответить
        • a < b? Нет. b < a? Тоже нет. Значит a == b.
          Ответить
          • Не факт. a == b тоже может не выполниться.
            Ответить
            • Ну четвёртый случай - UB, т.к. нарушает свойства отношения порядка. А на поведение при UB всем похуй. Так что все либы таки подумают, что a == b.
              Ответить
            • Собственно, что может получиться: http://ideone.com/yDG5HJ

              P.S. Интересно, можно ли так подобрать положение undefined'ов, чтобы quick sort вообще нихуя не отсортировал?
              Ответить
              • Это тупой алгоритм сортировки. Он не знает, что из того, что 4 < 100500 < 7 не выполняется, не следует, что 7 <= 100500 <= 4.

                Нужно изобрести алгоритм, который сравнивает в обе стороны, т. е. проверяет и less(a, b), и less(b, a).
                Ответить
                • Да умные тоже обосрутся. Они же не будут думать про четвёртый случай, когда из a < b и a > b не следует a == b. В самом-самом лучшем случае - ассёртнутся, когда увидят, что неравенство треугольника пошло по пизде.
                  Ответить
              • > P.S. Интересно, можно ли так подобрать положение undefined'ов, чтобы quick sort вообще нихуя не отсортировал?

                Результат сортировки состоит из отсортированных цепочек, соединённых друг с другом значением TEMPERATURE_UNKNOWN. Цепочки относительно друг друга вообще никак не упорядочены, хотя внутри каждой цепочки порядок.

                Если мы возьмём N нормальных значений, разделённых (N-1) элементом со значением TEMPERATURE_UNKNOWN, то можно надеяться, что сортировка ничего качественно не изменит.

                P.P.S. Зря понадеялся. Частично всё равно сортируется:
                http://ideone.com/xVulgU
                Ответить
                • P.P.S.
                  {9, SPECIAL, 8, SPECIAL, 7, SPECIAL, 6, SPECIAL, 5, SPECIAL, 4} → 4 5 6 7 8 9 100500 100500 100500 100500 100500
                  http://ideone.com/jfkBI1

                  {1, SPECIAL, 2, SPECIAL, 3, SPECIAL, 4, SPECIAL, 5, SPECIAL, 6} → 1 100500 2 100500 3 100500 4 100500 5 100500 6
                  http://ideone.com/t2EXmp
                  Ответить
                • по идее должно сортануть правильно, но с вкраплением ud в рандомных местах
                  Ответить
                  • Внимательно смотри примеры. Там не просто вкрапления.
                    Ответить
                    • ну вот если у тебя в примерах убрать 100500 то будут сортированный списки

                      пысы - у меня 12 ночи, сломалась мышка и жуткая лень - звиняйте если что не так
                      Ответить
                      • А что скажешь про следующую цепочку?
                        1 3 7 100500 100500 4 100500 100500 4 100500 9
                        Ответить
                        • а на говнокоде ее нету. исходная цепочка?
                          Ответить
                          • Исходная такая:
                            {7, SPECIAL, 3, SPECIAL, 4, SPECIAL, 1, SPECIAL, 4, SPECIAL, 9}

                            Чуть выше была ссылка, которую ты прозевал:
                            http://ideone.com/xVulgU
                            Ответить
                • Не, нахрапом тут не возьмёшь. Пойду исходники std::sort'а покурю.
                  Ответить
                  • Я нашёл одну неподвижную точку алгоритма:
                    {1, SPECIAL, 2, SPECIAL, 3, SPECIAL, 4, SPECIAL, 5, SPECIAL, 6}.
                    Ответить
                    • Короче там introsort - адовый гибрид сортировки вставками, хипсорта и квиксорта...

                      И на маленьких массивах, походу, должны юзаться вставки. А их не наебёшь кривым сравнением. В худшем случае просто не по ту сторону SPECIAL'а значение закинут.

                      А вот квиксорт в теории, можно пнуть по яйцам, вставив в начало, в конец и в середину SPECIAL. Тогда он посчитает, что все числа в массиве одинаковые и ничего не будет сортировать...
                      Ответить
                      • в общем поведение сильно зависит от входного массива и в общем случае непредсказуемо
                        Ответить
                        • Ну дык я и хочу специально сформированный массив скормить, который вообще не отсортируется.
                          Ответить

                          • {SPECIAL,SPECIAL,SPECIAL,SPECIAL,SPECIAL ,SPECIAL,SPECIAL,SPECIAL,SPECIAL}.


                            хотя он отсортирован по дефолту, но если юзать только операцию меньше, то сортироваться некоторыми сортировками он будет вечно
                            Ответить
                          • проще сортировать компоратором \ а, б -> rand(-1,1)
                            Ответить
                            • Компаратор нам дан свыше, автором кода. Его нельзя менять.

                              А вот если входными данными получится поломать сортировку, то есть вероятность триггернуть какие-то баги, стоящие после неё (если код надеется на упорядоченность) и, может быть, написать какой-то эксплойт :3

                              Враг вступает в город, пленных не щадя, от того, что в кузнице не было гвоздя.
                              Ответить
                              • Автор кода седовласый мудак с огромным ЧСВ.
                                Ответить
                                • наверное ему будет очень неприятно узнать, что его код обсирают анимешные девочки
                                  Ответить
                              • Самое интересно что русские программисты пишут эксплойты "чисто по приколу")
                                Ответить
          • а, вот о чем речь.

            Ну тогда включим безупречную логику
            Если температура не определена - то она может быть любой, что и отражается в этой функции - не определенная температура равна любой
            Ответить
            • Она не просто любая, она переменная. В примере Борманда (http://ideone.com/yDG5HJ) она в один момент оказалась меньше четырёх, а в другой — больше семи. Т. е. она может меняться прямо во время расчёта!
              Ответить
              • Ну так она неопределенная - логично чтог она не имеет постоянного значения там как бы зеленый был, да и тут не помешал бы
                Ответить
        • Эти три строчки ломают к хуям все математические свойства сравнения отношения порядка и превращают сортировки, поиск и мапы в треш с undefined behavior.
          Ответить
          • Даже в PHP такого нет... Угадайте с одного раза, в каком языке (1 > undefined) === false и (1 < undefined) === false.
            Ответить
          • Он юзает это добро как функтор в find_if.
            Это пищдец, гваждане.
            Ответить
            • Лол. Т.е. все TEMPERATURE_UNKNOWN вываливаются в ответ? :)

              Можно подробнее, как он его юзает для find_if?
              Ответить
          • ИМХО эта мапа вполне работоспособна, т.к. используется отношение порядка для std::string. А чтобы отсортировать эти хреновины в std::vector< std::pair<const std::string, WORD> > можно сначала выкинуть элементы с TEMPERATURE_UNKNOWN в конец коллекции при помощи std::remove_if, а потом отсортировать оставшееся. Но reinterpret_cast тут, конечно, нужен как рыбе зонтик.
            Ответить
            • Эта мапа работоспособна, да.

              Я про то, что этот Less нельзя юзать как компаратор для какой-то мапы. Да и вообще ни для чего нельзя.

              > можно сначала выкинуть элементы
              А можно просто пофиксить Less и не ломать голову...
              Ответить
      • сравнение же, какое "равна".
        Ответить
        • Тоже 20+ лет опыта в c++? :)
          Ответить
          • неа, про содомию плиска - согласен, но в 6 и 7 сравнение.
            Больше радует реинтерпрет каст к поинтеру и потом обратно к значению.
            Ответить
            • > но в 6 и 7 сравнение
              Ну и что? Из-за этих строчек получившийся Less в принципе непригоден для сортировки. И как компаратор для мапы. И для двоичного поиска. И даже для линейного поиска. Он вообще ни для чего не пригоден, если TEMPERATURE_UNKNOWN может попасться во входных данных.

              По сравнению с этим reinterpret_cast указателя на unsigned short (WORD же так определён?) в указатель на short и разадресация - это так, детская шалость... Ну хотя да, на разнице в размерах short и WORD можно тоже словить UB.
              Ответить
              • Тогда язык-который-нельзя-называть вообще ни для чего не пригоден.
                Ответить
                • Ты про богомерзкий жаваскрипт, писюн?
                  Ответить
                  • Он самый. Там и (1 < undefined) === false, и (1 > undefined) === false, и (1 == undefined) === false.
                    Ответить
                    • Причём тут JS, если дело в плавающем питухе?
                      Ответить
              • Он его юзает в
                Values::const_iterator const max_temp_it = max_element(temperatures.begin(), temperatures.end(), Less());


                Еще доставляет - const_iterator const.
                Ну вот накуя, а?
                Ответить
                • Чтобы итератор никто не подвинул случайно. У него вон даже bool const.
                  Ответить
              • http://ideone.com/mCm3Zh
                Ответить
                • http://ideone.com/BIBReO

                  Ooops...
                  Ответить
                  • БЛЬО!!!
                    Ответить
                  • С мапами та же пидрушка.

                    http://ideone.com/asWouQ
                    Ответить
                    • Хм, а тут мап вообще не при делах. Ты просто линейно обошёл его в порядке ключей, как массив.
                      Ответить
                      • Ну в реальном коде мапа.
                        Ясно, что макс_елемент просто проходит по всему контейнеру.
                        Ответить
                        • А реальный код map'а не юзает second. У него компаратор только на key (first).
                          Ответить
              • Суть в том, что это всё еще и на ARM запускается.

                В чём смысл подобных трюков? Зачем через указатели?
                Ответить
                • Да хуй знает. static_cast<short>(left.second) или (short)left.second хватило бы, чтобы беззнаковое в знаковое кастануть.
                  Ответить
              • А где разница в размерах?
                Ответить
                • Ну на какой-нибудь гипотетической платформе, где short не 16 (а 32 или 64, к примеру), а WORD задефайнен строго под 16. В жизни, скорее всего, не встретится. Но зачем создавать себе лишние проблемы? :)
                  Ответить
                  • Чувачку под 50, ему б продержаться, да еще и з/п попросить за борьбу с багами героическую.
                    Вот и говнокодит.
                    Ответить
                    • Блин, неужели и я когда-нибудь таким стану :( Надо будет выпилиться годам к 50, как только мозги начнут тупить.
                      Ответить
                      • Тоже так думаю.
                        Сидит, чавкает, кряхтит, жалуется.
                        Типичный долбодятел. Зато ЧСВ - пипец.
                        Ответить
                      • Вспомните, сколько лет Дональду Кнуту.
                        Ответить
                      • Можешь пойти преподавать.
                        Ответить
                      • просто разрядку им давай - найди нормальное хобби например - и все будет ок

                        У меня прабабушке уже 100 с хвостоком - мозги и память - дай Бог каждому. А все потому что не смотрит это ваше анимэ
                        Ответить
    • Strict Weak Ordering, сучки!!!
      Ответить
    • поясните для танкиста, в чем косяк в 10-11? reiterpret_cast где можно обойтись const_cast'ом? Или в использовании short вместо mapped_type / WORD?
      Ответить
      • Там намного проще можно, без всяких указателей:
        short signed_left = static_cast<short>(left.second);

        Переусложнение на пустом месте.
        Ответить
        • За 20 лет уже забыл, где какие касты нужны.
          Ответить
          • Сишный каст почти везде катит ;)
            Ответить
            • > Сишный каст
              Он слишком опасный, уж лучше использовать освящённый самим Страуструпом reinterpret_cast.
              Ответить
              • так то reinterpret_cast ничуть не безопаснее сишного. Более того, в некоторых ситуациях опаснее
                Ответить
                • зелёным же написано
                  Ответить
                • > Более того, в некоторых ситуациях опаснее
                  А в каких?
                  Ответить
                  • > А в каких?
                    Думаю, при касте потомка к родителю в случае множественного наследования у reinterpret_cast будут проблемы, а сишный каст сработает как надо.
                    Ответить
                  • если для сущности работает reinterpret_cast, но в то же время определен оператор преобразования
                    Ответить

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