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

    +58

    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
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    void Model::setPosition(GLfloat x, GLfloat y, GLfloat z) {
            if (m_position == NULL) {
                m_position = (float *) malloc(3 * sizeof(float));
            }
    
            if (m_position != NULL) {
                m_position[0] = x;
                m_position[1] = y;
                m_position[2] = z;
            }
        }
    
        void Model::setRotate(GLfloat x, GLfloat y, GLfloat z) {
            if (m_rotate == NULL) {
                m_rotate = (float *) malloc(3 * sizeof(float));
            }
    
            if (m_rotate != NULL) {
                m_rotate[0] = x;
                m_rotate[1] = y;
                m_rotate[2] = z;
            }
        }

    http://code.google.com/p/forget3d/
    Во первых, умиляет умение людей взяв современный супернавороченый удобный автомат, вместо того чтоб нажать на курок и выстрелить в противника, взять этот автомат наперевес как дубинку, и идти им пиздить противника по голове. Я о сишке, слегка прикрытой крестами.
    И во вторых, этот код при недостатке памяти просто нифига не делает, что чревато непонятками - вроде и повертел модель, вроде и подвинул, а оно никак не вертится и не двигается.

    Запостил: Pythoner, 27 Августа 2014

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

    • Недостатке памяти на три флоата? Я не думаю что для каких-то непоняток место останется, все равно все упадет.
      Ответить
    • Выделять память под три флоата из кучи само по себе странно.
      Ответить
    • >этот код при недостатке памяти просто нифига не делает, что чревато непонятками
      Недостаток памяти всегда чем-то чреват. И неважно где это на стеке или в куче.
      Edit: впрочем kipar выше об этом уже написал.
      Ответить
      • Ну если вовремя узнать о нехватке памяти, можно как то пытаться восстановить ситуацию, например, освободить память, занятую какими то не критичными данными.
        Ответить
        • Так что на каждом mallocе делать такую проверку?
          И если не хватает чистить все booststd::weak_ptr и кеши?
          Ответить
          • Традиционно это делается через коллбэк std::set_new_handler(), правда, для этого нужно использовать крестовый new, а не malloc, и следовать довольно нетривиальному протоколу.

            > чистить все std::weak_ptr
            А чего их чистить? Они вроде сами очищаются при уничтожении последнего shared_ptr, GC ждать не надо.
            Ответить
            • >Они вроде сами очищаются при уничтожении последнего shared_ptr
              Так нам надо их почистить не на последней ссылке, а по нехватке памяти.
              Ответить
          • > Так что на каждом mallocе делать такую проверку?
            Юзать new, оно кидает исключение.

            Ваш кэп.
            Ответить
            • Ну понятно что современные кресты и маллок это изврат.
              Ответить
            • Тут на хабре был срачек что - malloc дескать быстрее.
              Ответить
              • Пруфы они привели? :)

                Можно линк?
                Ответить
                • http://habrahabr.ru/company/pvs-studio/blog/234119/#comment_7891521
                  Ответить
                  • > Кстати, соглашусь. malloc() как раз и существует для случаев, когда нужно выделить неинициализированную память.
                    Они так говорят, как-будто new для примитивов что-то инициализирует.
                    Ответить
                    • int* p = new int(42); //Хотя с массивами не катит
                      Ответить
                      • Ну дык это ты явно указал параметр.

                        А если ты напишешь pod без дефолтного конструктора - там что new, что malloc нихера не будут инициализировать:
                        struct vec2 {
                            float x, y;
                        };
                        std::auto_ptr<vec2> p(malloc(sizeof(vec2) * n));
                        std::auto_ptr<vec2> p(new vec2[n]);
                        Ответить
                        • офтопа ради:
                          std::auto_ptr + malloc - не надо так
                          всё выделенное malloc-ом должно быть освобождено как free, а не delete
                          Ответить
                          • Массив тоже нельзя - его ведь через delete[] надо удалять. Так что оба моих примера - равноценная хуйня.
                            Ответить
                          • P.S. Но на POD'ах не упадёт. Хоть и неправильно.
                            Ответить
                          • std::auto_ptr - не надо так
                            Ответить
                            • Да блин, на днях на билдере кодил, вот выработалась вредная привычка. Там же кроме auto_ptr нихуя нет.

                              Я знаю, что его нельзя юзать для массивов.
                              Ответить
                              • Его вообще нельзя, он же deprecated
                                Ответить
                                • deprecated он только там, где есть то, на что его заменили - boost или новые кресты.

                                  В шестом говнобилдере он не deprecated.
                                  Ответить
                    • >> Кстати, соглашусь. malloc() как раз и существует для случаев, когда нужно выделить неинициализированную память.
                      operator new(size_t), не?
                      Ответить
            • Так говнокодеры будут использовать nothrow new, потому что «Исключения тормозят!!11»

              Или что-нибудь вроде
              Object* foo;
              try {
                  foo = new Object;
              } catch(...) {}
              if (foo) { //Пачему не работаит?!!
              //...
              Поскольку с исключениями работать не умеют
              Ответить
              • Дак реально же тормозят. Еще и бинарник раздувают. В LLVM/Clang, например, исключения не используются.
                Ответить
                • > Дак реально же тормозят.
                  В gcc - только когда бросаются. В остальное время они вообще никак не влияют, помимо раздувания бинарника

                  Там код с try/catch даже может работать быстрее кода с ифами, если исключение не бросается - на успешном пути не будет лишних проверок и переходов.
                  Ответить
                  • Поди подбери код в котором будет вероятность всех правых веткок ветвления будет близка к 100%. Искусственный код.

                    А так - да, Мне кажется так в любом языке - если исключения не выпадают то возвратов тупо нет.
                    Ответить
                    • Дык зачем всех веток то?

                      Ну вот не читается у меня файл, оборвался сокет, не спарсился XML - это всё ненормальные ветки, они не исполняются когда всё ок. Вот для них такие исключения идеальны, и код будет работать чуть быстрее, чем с if'ами.

                      А всё подряд на исключениях делать глупо, я не спорю. Если ветки равновероятны - какая ж это исключительная ситуация?
                      Ответить
                      • логично. Собственно так в нормальном коде и должно быть.
                        Ответить
                        • А для авторов питона исключительная ситуация это "ПАЦАНЫ, ЦИКЛ ЗАВЕРШИЛСЯ".
                          Ответить
                          • циклы чаще не завершаются, чем завершаются
                            Ответить
                            • Вот были бы там бесконечные списки, как в хаски - я бы понял и простил.
                              Ответить
                              • а я бы нет
                                Ответить
                                • Ну всё-таки конец бесконечного списка - это исключительная ситуация.
                                  Ответить
                                  • Ты так говоришь, как будто актуально бесконечные списки реально кому-то нужны. Всегда где-нибудь есть какой-нибудь take 15, делающий бесконечный список конечным.
                                    Ответить
                                    • >Всегда где-нибудь есть какой-нибудь take 15, делающий бесконечный список конечным.
                                      while (!solution_found())
                                      Ответить
                                    • > реально кому-то нужны
                                      С ними работать удобней - не надо базис индукции писать.

                                      Не помню, выкладывал ли я МНК, в котором строится бесконечная система уравнений с бесконечным числом переменных, а потом прямо так и приводится к треугольному виду. К сожалению последний шаг в бесконечности не получился ;(
                                      Ответить
                                      • Разумеется, промежуточные шаги трансформируют список как бесконечный. Но в конечном приложении, которое использует функцию-генератор, будет take или filter + head, как подсказывает \pi.

                                        Впрочем, я понял тебя - ты имеешь в виду функции, которые принципиально должны работать лишь с бесконечными списками (вроде преобразований эйлера для бесконечных рядов). Там исключение будет где-нибудь в head пустого списка :)
                                        Ответить
                                      • на моей памяти не выкладывал. Мне интересно, покажи
                                        Ответить
                                        • samples = [(1,1), (2, 3), (3, 4), (4, 4), (5,1), (6, -1), (7, -5), (8, -1), (9, 2)]
                                          
                                          -- Бесконечная система уравнений для МНК
                                          system s = zip (matrix s) (column s) where
                                              matrix = iterate tail . foldr1 (zipWith (+)) . map (\(x,y) -> iterate (*x) 1)
                                              column = foldr1 (zipWith (+)) . map (\(x,y) -> iterate (*x) y)
                                          
                                          -- Сведение бесконечной системы к треугольному виду (первый шаг гаусса)
                                          triangle (eq:eqs) = (eq : triangle (map (sub eq) eqs)) where
                                              sub eq1@(a1:as, ae) eq2@(b1:bs, be) = (zipWith f as bs, f ae be) where
                                                  f a b = b - a * b1 / a1
                                          
                                          -- Вычисление иксов (второй шаг гаусса)
                                          calcX n = foldr calc [] . take n where
                                              calc (a:as, b) xs = ((b - sum (zipWith (*) as xs)) / a : xs)
                                          
                                          -- метод наименьших квадратов
                                          mnk n = reverse . calcX n . triangle . system
                                          
                                          main = print $ mnk 5 samples
                                          Ответить
                                          • мнк - метод наименьших квадратов? вы где эти сокращения берете?
                                            Ответить
                                            • > вы где эти сокращения берете?
                                              ХБЗ.
                                              Ответить
                                              • КОМБ. ПНД
                                                Ответить
                                              • Хлебобулочный завод?
                                                Химическо-биологическая защита?
                                                Хлопчатобумажный зипун?
                                                Hemoglobin subunit zeta?
                                                Handwerksbildungszentrum?
                                                Hemorrhagic Bowel Syndrom?
                                                Ответить
                                  • прям как деление на ноль
                                    Ответить
                  • >В gcc - только когда бросаются. В остальное время они вообще никак не влияют, помимо раздувания бинарника
                    Эээ. Ну вообще-то всё зависит от выбранной схемы EH.
                    dwarf - без переголовы.
                    sjlj немного-таки просаживает пирфоманс, даже если исключение не бросается!
                    Ответить
                    • В gcc сейчас по умолчанию как раз zero cost exception handling через dwarf2. А схема с sjlj - пиздец лютый, хуже SEH даже.
                      Ответить
                      • >А схема с sjlj - пиздец лютый
                        Дадад. Когда будешь линковать с кодом скомпиленным с другим EH или вообще без инфы о unwinding (сишка) тогда поймешь ценность sjlj.

                        Кстати как там у dwarfa c 64-битными платформами?
                        Ответить
                        • Пидар.
                          Ответить
                        • Когда будешь писать под винду - тогда поймешь неизбежность sj/lj.
                          fxd

                          unwind через область с чужеродным EH - в любом случае игра на грани фола.
                          Ответить
                        • >Когда будешь линковать с кодом скомпиленным с другим EH или вообще без инфы о unwinding (сишка) тогда поймешь ценность sjlj.
                          Эээ, а как sjlj тут поможет?

                          >Кстати как там у dwarfa c 64-битными платформами?
                          Под юниксами есть, про венду не знаю. На IA64, кстати, dwarf -- стандартный способ делать EH.
                          Ответить
                          • >Эээ, а как sjlj тут поможет?
                            Через калбеки winApi dw2-исключение не пройдёт, sjlj - со свистом.

                            Борманд выше правильно поправляет: под виндой sjlj неизбежен. sjlj - совместимость, dw2 - производительность. Трейдофф.
                            Ответить
                            • Ну, при желании, можно и дворфов поюзать. У мингв, емнип, даже соответствующая сборочка есть. Но там они сразу предупредили - исключения через коллбеки не пролезут.
                              Ответить
          • Формально, там проверка как раз есть. И если памяти нет, то ничего не делать :)
            Ответить
    • На правах капитана очевидность. Нажимать на курок автомата - очень и очень неудобно, потому что он обычно находится внутри ствольной коробки.
      Ответить
      • И в свете этого комментарий приобретает новый смысл: вместо того, чтобы делать через ту жопу, через которую делает большинство, говнокодер нашёл новую.
        Ответить
    • Сразу не обратил внимание.
      Здесь принимается что sizeof(GLfloat) == sizeof(float), что логически вроде и обосновано, хотя стандарт этого не обещает. Интересно, есть ли системы где это не так?
      Ответить
      • > Здесь принимается что sizeof(GLfloat) == sizeof(float)
        Нет. Мы ведь не видим определений m_position и m_rotate. Если там просто float - то всё норм...
        Ответить

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