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

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
  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 Pythoner, (Updated )

Комментарии (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() как раз и существует для случаев, когда нужно выделить неинициализированную память.
                  Они так говорят, как-будто new для примитивов что-то инициализирует.
                  Ответить
                    • Ну дык это ты явно указал параметр.

                      А если ты напишешь 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[] надо удалять. Так что оба моих примера - равноценная хуйня.
                          Ответить
                          • Да блин, на днях на билдере кодил, вот выработалась вредная привычка. Там же кроме auto_ptr нихуя нет.

                            Я знаю, что его нельзя юзать для массивов.
                            Ответить
                  • >> Кстати, соглашусь. 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
                                        Ответить
                • >В 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 - то всё норм...
      Ответить

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

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

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


    8