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

    0

    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
    // почему это гавно не будет работать?
    auto size = buffer.size() - 1;
    auto *ptr = new byte[size];
    for (auto i = size; i >= 0; i--)
    {
        ptr[i] = 0;
    }
    
    // a это гавно будет работать :)
    auto size = buffer.size() - 1;
    auto *ptr = new byte[size];
    for (int i = size; i >= 0; i--)
    {
        ptr[i] = 0;
    }

    почему это говно не будет работать?

    Запостил: ASD_77, 17 Марта 2021

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

    • Ответ: по мнению стандарта и тот и другой варианты — UB. ptr[size] за пределами массива.

      А так да, камешек в огород любителей беззнаковых значений.
      Весело будет, если size() вернёт когда-нибудь 0
      Ответить
      • >ptr[size]
        вроде, туда ходить можно, а разыменовывать нельзя, не?
        или это тока для указателей

        впрочем, лунь туда один хуй пишет
        Ответить
        • ptr + size можно написать, это ещё валидный указатель. Но разыменовывать его нельзя. А скобки вроде как уже подразумевают разыменование, даже если ты получившееся lvalue потом не юзаешь. Читать и писать тем более нельзя.
          Ответить
        • так супскрипт невяно разъебенует
          Ответить
    • Шо то хуйня, шо это хуйня...

      Массив маловат.
      Ответить
    • > auto size = buffer.size() - 1;
      < size = -1
      > new byte[ -1];
      < говно
      Ответить
      • Там не -1 если чо, размеры в крестах беззнаковые. Но аллокатор всё равно bad_alloc кинет, да.
        Ответить
        • там size_t будет с каким-то говном внутри?
          Ответить
          • Ну да, когда ты совершаешь операцию над знаковым и беззнаковым интом, то знаковый кастуется к беззнаковому (охуенно интуитивно, ага).
            Ответить
            • и так трудно, а еще auto эти дурацкие пишете.. если бы там был size_t, то я бы допёр

              вообще, ауты нужны, чтобы параметризованные итераторы не выписывать. А для простых типов я бы его не
              Ответить
              • Именно поэтому я против auto в тех местах, где конкретный тип не на километр.
                Ответить
                • И в шаблонах можно, где ты шо так шо эдак конкретного типа не знаешь.

                  template<typename T> example(T t) { T::value_type x = t[i]; } → example(T t) { auto x = t[i]; }
                  Ответить
                  • У вас typename перед T::value_type отклеился. Или я туплю?
                    Ответить
                    • Там ещё возвращаемый тип, объявление i и полезные действия с x отклеились :). А так да, зависимому типу нужно указывать, что он тип.
                      Ответить
                      • Да я просто на днях портировал код с msvc на шланг, теперь вот отходняки, зависимые типы без typename глаза режут.
                        Ответить
                  • сложная хуйня какая-то .. пиши так

                    auto example(auto t) { decltype(t[i]) x = t[i]; }
                    Ответить
              • Подтверждаю. Меня как-то вербально отпиздили за то что мои var (речь про другой язык) на ревью нихуя не понять что за собой скрывают. Тогда-то я и Понял.
                Ответить
      • а вот и нет. т.к. размеры это беззнаковый типа то auto size = (size_t) 0 - 1 = 0xfffffffff а это есть положительное число
        Ответить
        • а стандарт гарантирует, что переполнение нормально отработает, или будет UB?

          unsigned int i = 0;
          i--;
          равен ли он теперь MAX_INT?
          Ответить
          • Для беззнаковых есть гарантия. Для знаковых UB.
            Ответить
        • g: size_t max value

          So the minimum maximum value that size_t must be able to hold is 65535, which is 16 bits of precision, and size_t is only defined to be an unknown unsigned integer type.

          Какой анскилл )))
          Ответить
    • Оптимизировал:
      auto *ptr = calloc(size, 1);

      З.Ы. Вроде ещё что-то типа такого можно, но я не уверен:
      auto *ptr = new byte[size]();
      Ответить
      • А нельзя разве как со обычным моссивом new byte[size]{0}?
        Ответить
        • Можно. Чет я не подумал.
          Ответить
          • З.Ы. Бля, когда я последний раз массив в куче инициализировал? В лабе разве что. И то не факт.
            Ответить
            • Когда ты последний раз вообще new писал? небось до ++14, когда make_uniq завезли всякие?
              Ответить
              • Собеседующий: что делает оператор delete
                Борманд: да хуй знает, не юзал ни разу
                Ответить
                • --у вас в С++ ручное управление памятью
                  --А разве не RC, как в ObjC?
                  Ответить
                  • -- у вас в С++ ручное управление памятью
                    -- нет, это у вас в джаве ручное управление ресурсами
                    Ответить
                    • да и памятью тоже
                      https://stackoverflow.com/a/8191493
                      Ответить
                    • -- у вас в С++ ручное управление памятью
                      -- У вас вообще его нет

                      самое печальное с жабой и другими мейнстримовыми языками без управления памятью - что сервисы для перемалывания больших данных, запросов, etc. пишут именно на них, а вот ограничить сверху расход памяти конкретным запросом/джобой невозможно, и потому какие circuit breaker'ы не ставь, всё равно рано или поздно не успеешь отловить OOM,
                      Ответить
                      • в C# можно хотя бы изъебнуца со стеком через value types, а в джавке есть этот.. Шипилёша сделал.. GC, который ничего ничего не чистит. Сразу выделяет память, и как только ты ее заполнил -- получи OOM
                        Ответить
                        • В джаве тоже можно как-то память вручную аллоцировать, но это всё равно мертвому припарки, придется писать свой надязык чтобы в этом размещать свои типы. А вообще стека не хватит на то, про что я говорю, речь о всяких штуках, которые могут попробовать гигабайт себе захватить.

                          Именно поэтому у меня есть очередная NIH-мечта - выкинуть нахуй Lucene и написать всё по-человечески на сишке.
                          Ответить
                          • > по-человечески

                            По-царски.
                            Ответить
                          • > выкинуть нахуй Lucene и написать всё по-человечески на сишке

                            Хм, а CLucene это не то?
                            Ответить
                        • А, хотя один пуленепробиваемый вариант есть. Форкать процесс, возвращать оттуда результат, и позволить при необходимости ООМнуться. Только хахахаха он же перед ООМ пойдет делать GC да кучу дефрагментировать, т.е. вся эта ваша CoW память сразу в пизду, а это значит каждый форк будет жрать столько же, сколько родительский процесс, а так как динамически максимальный размер хипа толком не потюнить, то придется все процессы сразу создавать с таким хипом, чтобы в него эти гигабайты могли поместиться, а это в лучшем случае свап, в худшем счет от амазона за терабайт оперативы.

                          Тут конечно можно сказать: зачем форкаться, если можно создать новый процесс? А новый процесс это инициализировать новую вм ахаххаха опять весь пирформанс в пизду.
                          Ответить
                          • форкать джаву?чтобы она там прогревалась и джитилась каждый раз?
                            Ответить
                            • А ты прогрей, а потом форкай.
                              Ответить
                              • пиздец сколько ебанины вместо того, чтобы взять яп с RC
                                Ответить
                              • блядь, у меня и так счета за отопление пиздец, а ты тут это
                                Ответить
                            • Форк-то как раз прогревать не надо, в этом плане с ним всё в порядке. Вот то что память нихуя не переиспользуется, как при форке приложения на нормальном языке - это да.
                              Ответить
                              • > память нихуя не переиспользуется

                                Ну если хорошенько прогреть, чтобы всё проджитилось, gc несколько раз отработал и убрал всю статику в олдфажное поколение, вроде должно норм получиться.

                                Форк насрёт в быстрое поколение и сдохнет, а жирный общий контекст останется расшаренным.
                                Ответить
                                • Мы говорим про приложения, которые перемалывают гигабайты. Фулл ГЦ придет очень быстро и пересоберет всю кучу.
                                  Ответить
                              • расскажи про форк. Почему не нужно прогревать? Потому что корова уже прогрета, и она шарица?
                                Ответить
                                • Потому что прогрев - это компиляция методов согласно собранным профилям, и да, дочерние процессы получат уже прокомпилированные компилятором второго уровня методы.
                                  Ответить
                                  • я пнял, да. Если ты не сделаешь exec поверх форка, то секция кода у тебя та же будет

                                    Кстати, как ты это сделаешь в винде?
                                    Ответить
                                    • винда не нужна

                                      хз, я просто не знаю достаточно про винду, только про то что ты имеешь в виду что там вместо fork-exec StartProcess, который ничего не шарит
                                      Ответить
                                      • CreateProcess там, угу.

                                        В никсах ты делаешь fork, получая копию себя (благодаря корове очень дешевую), а потом ты делаешь exec поверх если хочешь.

                                        В пинде ты явно запускаешь новый процесс.
                                        Конечно, если ты перезапускаешь то, что уже есть в памяти, то винда может постараться переиспользовать странички c кодом, но я не ебу что там с джитом будет.

                                        А вместо fork там потоки.

                                        зы: Борманд наверняка знает
                                        Ответить
                                        • > но я не ебу что там с джитом будет

                                          Заново джитить всё будет.

                                          Цыгвин как-то пытается "форкнуть" процесс на венде (через явное шаред мемори?) но там куча проблем с этим, это вообще не продакшен-реди.
                                          Ответить
                                          • Мне птичка напела, что само ядро имеет сискол fork (для почившей в бозе юниксовой подсистемы) но в Win32API он не распаян
                                            Ответить
                          • И тут блядь его осенило

                            https://github.com/elastic/elasticsearch/issues/70522
                            Ответить
                            • Фу, у тебя пхп в профиле


                              нафоркай себе сколько-то долгоживущих процессов, создай direct buferы в обычной памяти заранее заданного размера, и не вылазть за них

                              placement new в жову не завезли, так что придется тебе вместо объектов массивами оперировать, как Царь

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

                                  не пробовал его?
                                  Ответить
                                  • Боротьба с GC напоминает мне войну с отсутствием стат типизации в мире питоноблядей или борьбу с отсутствием классов в старом JS или перле.

                                    Зачем бороться с тем, что тебе не подходит?
                                    Выкини, да возьми другое.

                                    Управляемая куча говна не лучший инструмент для высокоперформансного хайлоада бигдаты
                                    Ответить
                                    • > Выкини, да возьми другое.

                                      Именно поэтому я за кресты. Там говно на любой вкус есть. Даже gc и jit при желании.

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

                                      тут мы возвращаемся к исходному сообщению

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

                                      нету другого эластика и другого люсина
                                      Ответить
                                      • http://sphinxsearch.com/about/sphinx/
                                        Ответить
                                        • он и в подметки не годится

                                          > Partitioning is done manually.

                                          дальше уже и читать смысла особо нет
                                          Ответить
                                      • > нету другого эластика и другого люсина

                                        CLucene протух, получается? Какая-то уж больно древняя версия у него по сравнению с настоящим.
                                        Ответить
                                        • Я даже не слышал про него, что видимо означает да. Люцен очень активно всякую хуйню добавляет, хотя вместо этого лучше бы позаботился о глазных кровотечениях при попытках разобраться в коде.
                                          Ответить
                            • деанон?
                              Ответить
                        • > Сразу выделяет память, и как только ты ее заполнил -- получи OOM

                          Т.е. "PHP" всё-таки не говно, раз его основной принцип перенесли в жабу?
                          Ответить
                          • ну в джаве много чего есть от PHP, например вот

                            https://www.codejava.net/java-ee/jstl/jstl-sql-tag-query
                            Ответить
                  • — У меня ОС всегда сама после завершения приложения память подчищала.
                    Ответить
                    • сверху можно атомной бомбой полирнуть, чтоб наверняка
                      Ответить
                      • запустить машину в космос лучами пооблучаться
                        Ответить
                      • Да, с PHP только так.
                        Ответить
                      • Вы смеётесь, а тов. dxd (кстати, где он?) тут постил код из какой-то питушни на фортране, типа gaussian, где была функция hbomb, роняющая программу.
                        Ответить
    • кароче прикол в том что если сделать size = uint_t то цикл никогда не закончиться потому что i никогда не будет ниже нуля :)
      Ответить
      • Надо предупреждения включать:

        warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
        Ответить
        • Не поможет.

          for (size_t i = 0; i < pidor_v.size()-1; ++i) { // итерируемся до предпоследнего
          Ответить
          • Ну я же про конкретную ошибку, когда пытаешься устремить i к нулю, а оно беззнаковое. Понятно, что все ситуации не отловить, это же не coq.
            Ответить
          • какой багор:) Это нужно явно проверять каждый раз, что вектор не пустой?
            Ответить
            • В общем-то нет, если ты хочешь просто все элементы обработать. А здесь же "все кроме последнего", т.е. должен быть как минимум последний, т.е. надо убедиться что не пуст.

              Хотя со знаковым числом этой фигни бы не было, конечно.
              Ответить
              • Ну я про это и говорю, бо если я из ноля вычту 1, то получу оче большое значение же, и уйду за пределы массива

                со знаковым я бы получил -1, а 0 не меньше -1, и все кончилось бы хорошо, не?
                Ответить
            • Так приводи к инту
              Ответить
          • Из серии «хотелось бы как-то возразить, да нечем»

            Кампутир сайенс положил семантику на лопатки
            Ответить
          • Пофиксил:

            for (size_t i = 2; i < pidor_v.size(); ++i) {
            . . . . auto j = i - 2;

            Ладно, побежал дальше писать работающие программы на unsigned вычислениях, а вы продолжайте хуесосить ЛУЧШЕЕ, что когда либо было создано в программировании ;)
            Ответить
    • https://pbs.twimg.com/media/EwsZKGvWUAA7YHV?format=png&name=900x900
      Ответить
      • москали соснули, говно из сливных отверстий сухарных мишочков будет заливать квадратную барсетку
        Ответить
    • Теперь будет работать как надо:

      #define UNSIGNED_NIL UINT_MAX
      
      /* тут еще всякий код */
      
      for (auto i = size; i != UNSIGNED_NIL; i--)
      {
          ptr[i] = 0;
      }
      Ответить
    • Беззнаковый размер в крестах - это ублюдская историческая ошибка, которую признали и дохлый страус, и любитель тухлой рыбы.
      Ответить
      • Именно поэтому я за "PHP".
        Ответить
      • А любитель дохлой рыбы - это кто?
        Ответить
      • но ведь по типу все верно . кол-во не может быть меньше нуля.
        Ответить
        • зато нельзя сделать так
          if (size - 1 > 0)..

          нужно было делать как с указателями: чтоб вылазить за пределы ( в отрицательные значения ) было можно, а обращаться по ним нельзя
          Ответить
          • > if (size - 1 > 0)

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

              Вдруг мои вкусы специфичны, и я именно это и хотел написать?
              Ответить
          • Кстати на тебе ещё прикол:
            int size = 3;
            
            if (size - sizeof(uint32_t) > 0)
            Т.е. если менять тип, то вообще везде. Один unsigned может всё выражение зашкварить.
            Ответить
            • size перватится в unsigned int, и будет true?

              а если бы я сказал size = -1, то что бы случилось? unsigned превратился бы в signed?
              Ответить
              • > unsigned превратился бы в signed

                Наоборот же. Будет 0xFFFFFFFFu - 4u > 0u.
                Ответить
                • я просто не помню, какие типы во что расширяются.
                  помню тока, что операторы любят, чтобы операнды были одинакового типа)

                  вообще имплиситный каст есть говно, и лучше бы его не было
                  Ответить
                  • Блядь, да там пиздец...

                    Сначала мелочь меньше инта кастится в int. Затем, если получились типы разного размера, то кастится в больший из них. А если одного -- то в беззнаковый.
                    Ответить
                    • нужно смешать это с перегрузкой, и задавать задачки на собеседовании типа "какая из восьми перегрузок метода вызовется в foo(bar - buz)"
                      Ответить
                      • void foo(int&& x);
                        void foo(unsigned&& x);
                        
                        uint8_t a, b;
                        foo(a + b);
                        Какой метод вызовется?
                        Ответить
                        • хм, зачем мувать инты?

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

                          блядь

                          там же создасца временная переменная и будет наоборот: вызовеца unsgined, а мог бы и вообще какой-нить float?
                          Ответить
                          • Ну да, создастся временный int, поэтому вызовется перегрузка с int&&.
                            Ответить
                            • вообще за такие перегрузки нужно с вертушки пробивать, я считаю.

                              Перегружать можно только то, что друг а друга не расширяется неявно
                              Ответить
                          • не адщфе, а вщгиду, расширение же типа идет
                            Ответить
                • >FFFFFu
                  https://i.kym-cdn.com/entries/icons/original/000/000/063/Rage.jpg
                  Ответить
                  • https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTDy0vp7fj7I2Z7eTwdukh yRjmNAwca-rK6iQ&usqp=CAU
                    Ответить
              • А вот на более очевидное if (size > sizeof(uint32_t)) конпелятор таки ворнингует.
                Ответить
            • хоть бы шкворнинг кидал
              Ответить
    • Десять лет назад 500 мегабайт интернета стоили как сейчас безлимит.
      А всё потому что это был чистый концентрированный на сто процентов свободный интернет.
      Нынче такой интернет не делают, всё разбавлено цензурой, вот и продают за бесценок.
      Ответить

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