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

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    #include <iostream>
    #include <map>
    
    int main()
    {
      std::string name;
      std::map<int, int> m = { {1, 1}, {2, 2} };
      m.erase(m.end());
      std::cout << "Kokoko " << m[1] << std::endl;
    }

    На моем проекте уходит в бесконечный цикл.

    Запостил: YpaHeLI_, 08 Июня 2021

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

    • сразу видно аура плохая
      Ответить
    • > m.erase(m.end());

      Лолшто.
      Ответить
      • удалять после конца

        Кстати, вы будете семяца, но про это даже прямо на цппрейференс написано

        The iterator pos must be valid and dereferenceable. Thus the end() iterator (which is valid, but is not dereferenceable) cannot be used as a value for pos.

        Уранец наверное пытался сделать UB, и посмотреть, что будет
        Ответить
        • > и посмотреть, что будет

          Прямо как про лом и унитаз в поезде...
          Ответить
          • я думал, что это всё еще осуждение бройлера, который на одном месте завис и что-то там рассматиривает
            Ответить
          • Вообще нящная поднасрала конечно своей идеей этого указателя. Он сделан конечно чтобы было удобно делать цикл, но было бы лучше придумать другую идиому, чем выдумывать какой-то неразыменовываемый указатель (единственный в своем роде)
            Ответить
            • Да нят, это хорошая абстракция. Как ты иняче сделаешь end()?
              Ответить
              • "islast(foo)" какой нить

                ну правда методы придется переделать, чтобы они удаляли по указатель включительно
                Ответить
                • У [x, y] есть большая проблема по сравнению с [x, y): сложно записать пустой интервал. Именно поэтому почти везде в программировании юзается полуоткрытый интервал.
                  Ответить
                  • Можно было бы сделать идиому для пустова интервала

                    Правда это тоже было бы мерзко
                    Ответить
                    • > Правда это тоже было бы мерзко

                      В паскале из-за этого приходилось писать "от 0 до -1" уводя индексы в минус, угу. Ну или if'ы лепить, чтобы пустой кейс отдельно обрабатывать.

                      З.Ы. Короче сишный вариант -- это меньшее зло, как мне кажется.
                      Ответить
                      • Ну я и предложил ввести какую-то конструкцию языка или какой-то приём чтобы не писать if. А какой -- надо подумать.

                        Я вполне верю, что сишный вариант взяли не с потолка, а потому что были какие-то проблемы, но сам по себе он тоже не оч хороший, пушо вводит понятие "неразыменовываеемымымымй указатель", а потом уранцы вон код пишут
                        Ответить
                        • > чтобы не писать if

                          Дык конструкция языка просто заметёт эту проблему под ковёр. В реализации этой конструкции один хуй будет или if или end < begin.

                          Тлен и безысходность.
                          Ответить
                          • Дак пофиг что будет в реализации, важно что программист не должен будет "не забывать обработать особый случай" (это самое говно)

                            >Тлен и безысходность.

                            ладно, убедили. Эскобар.jpg
                            Ответить
                            • Дык в сишном варианте как раз нет особых случаев!

                              Пустой интервал ничем не отличается от любых других. Да ещё и длину считать легко, всего одно вычитание. Просто юзай end() по назначению и будет тебе счастье.
                              Ответить
                              • В сишнком нет осотых случаев в случае итерации по массиву, это правда.

                                А вот один "особый случай" показал нам Уранец.
                                Ответить
                                • > показал

                                  А ещё можно местами поменять begin() и end(). Тоже "смешно" будет.
                                  Ответить
                                  • смотри: он передает end() туда, где ждут начала интервала

                                    он совершенно искренне думает, что должен получиться пустой интервал, а получился UB

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

                                    Так что сишкино решение тоже не идеально
                                    Ответить
                                    • > Так что сишкино решение тоже не идеально

                                      А кто говорит, что оно идеально? Просто меньшее из джвух зол.

                                      В джаве пустой итератор тебя тоже экцепшоном ёбнет, кстати, если ты полезешь к нему в next().
                                      Ответить
                                    • void erase (iterator position);
                                      position: Iterator pointing to a single element to be removed from the map.


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

                          А это естественная концепция, кстати. Иначе на пустом интервале тебе придётся запретить begin(). Вообще. Потому что его там тоже не разыменовать.
                          Ответить
                  • [0, 0]?
                    Ответить
                    • Он не пустой, там два нуля.
                      Ответить
                    • Этот отрезок содержит ноль. Он не пуст.

                      [0, -1] тогда уж, как в паскале делали. Но это выглядит как говно, особенно с точки зрения ма-те-ма-ти-ки.
                      Ответить
                      • на всякий случай няпомню, что для индексации массивов может использоваться size_t , а он унсигнед

                        Читаемость паскалевого стиля тоже сомнительна..
                        Ответить
                      • а []? пустое множество типа?

                        а потому что надо было послать нахуй математику, знаковый size с точки зрения математики и здравого смысла тоже говно, но все едят, потому что кампутиру так проще
                        Ответить
                        • > но все едят, потому что кампутиру так проще
                          В С++ не едят. Поэтому, если пользуешься стандартной либой, приходится или использовать беззнаковый тип или отключать варнинги о нарушении сегрегации по знаковому признаку.
                          Ответить
                          • Там еще можно ловко отсосать вычтя единичку и забыв предварительно проверить на нолик

                            Получится вполне себе нормальное число, даже стандарт не нарушится
                            Ответить
                        • Ну и если индекс и размер одного типа, то можно использовать невозможный индекс -1 (find(...) не найдено)
                          Ответить
                          • Sentinel values вроде индекса -1 — это, няверное, самое плохое, что сохранилось с тёмных компьютерных времён. Единственный их плюс — отсутствие някладных расходов во время возврата, во всём остальном они — пример исключительня ужасной архитектуры.

                            См. https://abseil.io/tips/171 .
                            Ответить
                            • А по моему они не очень страшные, если речь идет об интах, правда конечно "-5" в примере нужно вынести в ``ERR_GOVNOTFOUND``

                              А вот если речь идет НЕ об интах, а например о енумах или указателях на класс (см паттер Null object), то конечно они кал, бо срать в домен костылями не комильфо

                              Но разумеется optional лучше всегда
                              Ответить
                              • Они страшные т.к. разрушают систему типов.

                                По-хорошему это -5 и нормальные числа должны быть в разных ветвях ADT, чтобы типизация вообще ну никак не давала смешать их между собой или забыть обработать какой-то кейс: Error -5 но Size 42. Но нормальных ADT в мейнстримных языках нет, только костыли в духе optional.

                                З.Ы. А для скриптушни похуй, конечно. Там и так про типы никто не парится.
                                Ответить
                                • В правильном мире каждый тип описывал бы ровно те значения, которые имеют для него смысл.

                                  Для примера выше, ``AccountBalance`` вообще не мог бы быть signed.

                                  Плохо, что там -5, и плохо что от валидного баланса к ошибке можно перейти простой арифметической операцией

                                  Но я видел код, где люди ищут в сообщении об ошибке подстроку, и строят на этом логику.
                                  И да: сообщение это локализованное.

                                  Так что ERROR как -1 не так и страшны
                                  Ответить
                                  • > ``AccountBalance`` вообще не мог бы быть signed

                                    Технический овердрафт смотрит на тебя с непоняманием...

                                    Будет забавно, если чел перебрал на 5 рублей и теперь его банк-клиент крашится с ошибкой access denied потому что -5.
                                    Ответить
                                    • Я увидел там "-5", и сделал вывод, что конкретно на этом уровне абстракции там не может быть отриц значений

                                      Потому что если может быть, то ты сам описал, что будет))
                                      Ответить
                                      • Ну я о том, что в поле AccountBalance очевидно могут быть отрицательные значения.
                                        Ответить
                                        • Мне не очевидно.

                                          Это может быть баланс на счету в Интернет магазине. Там отрицательных значений быть не может (магазины в кредит не торгуют)

                                          Есть еще мой "любимый" вид ошибки как в COM HRESULT, где в четырехбайтный инт упаковали severity и facility

                                          Глупые программы выдают его как обычное число, потом у тебя ошибка "2147500037"
                                          Ответить
                                          • > магазины в кредит не торгуют

                                            Лолшто.
                                            Ответить
                                            • ээ
                                              а что, можно купить в интернет магазине что-то, уйти в минус, и потом через месяц загасить долг?
                                              Ответить
                                              • В мелких нельзя, а большие вроде вполне дают онлайн рассрочку. Любой каприз за ваши деньги.
                                                Ответить
                                          • $ err 2147500037
                                            # for decimal -2147467259 / hex 0x80004005
                                              DDERR_GENERIC                                                  ddraw.h
                                              DIERR_GENERIC                                                  dinput.h
                                              DSERR_GENERIC                                                  dsound.h
                                              STIERR_GENERIC                                                 stierr.h
                                              DRM_E_FAIL                                                     windowsplayready.h
                                              E_FAIL                                                         winerror.h
                                            # Unspecified error
                                            Ответить
                                            • Верно. Но кусочек HRESULTа специфичен для сервиса, так что если у тебя кастомный сервис, то err.exe про него может и не знать (он по .h файлам SDKов собирает ошибки вроде)

                                              https://en.wikipedia.org/wiki/HRESULT#HRESULT_format
                                              Ответить
                                            • > Der Generic
                                              > Die Generic
                                              какие прононсы )))
                                              Ответить
                              • З.Ы. Можно попробовать сделать воркэраунд в духе ErrorOrSize вместо int'а. Внутри он компактно хранит ошибки как отрицательные числа, а размер как положительные. Но снаружи юзер об этом знать не должен, а должен юзать res.is_eror(), res.get_error() и res.get_size().

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

                                  В джаве дураки придумали хуёвый Optional и он выглядит как говно

                                  Единственный нормальный способ обработки ошибок это такая манда, которую паттернмачишь, и из нее вылазит либо ошибка, либо результат

                                  Любой код, где надо писать
                                  if (govnoOrKonfetka.has_konfetka()) 
                                  {
                                     std::cout << govnoOrKonfetka.value()
                                  } else {
                                     std::cerr << govnoOrKonfetka.error()
                                  }

                                  похож на Go
                                  Ответить
                                  • Манту не надо патернячить, она сама разберётся с пробросом ошибки дальше. В том и фишка, что это почти как исключение. Ну, если ты не хочешь явно обработать ошибку, конечно.
                                    Ответить
                                    • я имел ввиду явную обработку, а в общем случае еще лучше, да)

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

                                        Кстати, checked исключения, в принципе, очень похожи на монадическую обработку ошибок -- ты либо паттерн-няшишь ошибку через try либо она форвардится дальше (при этом у тебя в типе функции это явно указано).
                                        Ответить
                                        • В котлине все исключения не checked. Узнать что функция может вернуть ошибку исключением можно только по документации, которую никто не пишет.

                                          Потому у нас в проекте в случайных кусках кода то тут, то там расставлены catch, которые ловят всякие разные исключения.

                                          Где увидели ошибку в логах, туда и воткнули catch.

                                          Checked исключения в джаве действительно решали эту проблему, но они были настолько отвратительными (и тяжелыми, если стек трейс не отключить), что ими никто не пользовался.

                                          Котлиновцы еще умеют возвращать null в случае ошибки (null safety это проверяет), но саму ошибку ты не вернешь.

                                          Мне советовали юзать вот
                                          https://arrow-kt.io/docs/0.10/patterns/error_handling/#either

                                          но поскольку это не в стандартной библиотеке, то разумеется нигде и неиспользуется

                                          Потом они завезли вот
                                          https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/

                                          но тут ошибкой может быть только Throwable, что (имхо) тупо
                                          Ответить
                                          • > ошибкой может быть только Throwable

                                            Да сойдёт, наверное... Тебе же с джавой интегрироваться всё-таки. Может понадобиться дальше прокинуть как исключение.

                                            С другой стороны без монад явная обработка ошибок нахуй не нужна. Привет, го.
                                            Ответить
                                            • ну так я и оберул бы в том месте

                                              Я могу хотеть вернуть строку ошибкой, нафиг мне ее заворачивать:)

                                              У нас для котлина был напилен свой sealed class, который можно было паттернматчить

                                              Ты получаешь абстрактрный Result<Petuh, Error> и матчишь его.
                                              Он либо наследник Error, либо Petuh.
                                              Ответить
                  • Кстати да

                    В бинарном поиске если итерироваться по полуоткрытому с конца интервалу то всегда искомое значение != верхней границе и меньше кейсов нужно обработать
                    Ответить
    • братишки, я вам принес
      https://pbs.twimg.com/media/E3WKlxLWEAImmtr?format=jpg&name=900x900
      Ответить

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