Кресты / Говнокод #19061 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 blackhearted, (Updated )

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

  • Тут гораздо больше отжигают 6-8 строки, из-за которых TEMPERATURE_UNKNOWN будет равна любому другому значению...
    Ответить
          • Ну четвёртый случай - 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
              Ответить
              • по идее должно сортануть правильно, но с вкраплением ud в рандомных местах
                Ответить
                  • ну вот если у тебя в примерах убрать 100500 то будут сортированный списки

                    пысы - у меня 12 ночи, сломалась мышка и жуткая лень - звиняйте если что не так
                    Ответить
              • Не, нахрапом тут не возьмёшь. Пойду исходники 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}.


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

                            А вот если входными данными получится поломать сортировку, то есть вероятность триггернуть какие-то баги, стоящие после неё (если код надеется на упорядоченность) и, может быть, написать какой-то эксплойт :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 и не ломать голову...
            Ответить
        • неа, про содомию плиска - согласен, но в 6 и 7 сравнение.
          Больше радует реинтерпрет каст к поинтеру и потом обратно к значению.
          Ответить
          • > но в 6 и 7 сравнение
            Ну и что? Из-за этих строчек получившийся Less в принципе непригоден для сортировки. И как компаратор для мапы. И для двоичного поиска. И даже для линейного поиска. Он вообще ни для чего не пригоден, если TEMPERATURE_UNKNOWN может попасться во входных данных.

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


              Еще доставляет - const_iterator const.
              Ну вот накуя, а?
              Ответить
            • Суть в том, что это всё еще и на ARM запускается.

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

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

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

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8