1. Си / Говнокод #17250

    +131

    1. 1
    2. 2
    // bg_pmove.c -- both games player movement code
    // takes a playerstate and a usercmd as input and returns a modifed playerstate

    Дальше идут 11 тысяч строк нечитаемого говна. Это вообще нормально?!

    Запостил: gost, 03 Декабря 2014

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

    • Подходил к своему завершению 2014-й год...
      И тут вдруг в сети оказались исходники кваки!
      Ответить
    • Книгу "Структурное программирование" написали в 1975 году, скорее всего автор этого кода тогда еще даже не родился.
      Но некоторые люди умудряются в своем профессиональном развитии иметь отрицательный возраст.
      Ответить
      • Гейдевки говнокодеры еще те и всегда ими были.
        Ответить
      • Чуваки, расслабтесь, это Кармак написал. Напишите что то покруче, а потом поливайте говном.
        Ответить
    • а пример где?
      Ответить
      • Не так всё плохо, кстати

        https://github.com/id-Software/Quake-III-Arena/blob/master/code/game/bg_pmove.c
        Ответить
        • да, gost похоже не видел щи
          http://govnokod.ru/9903
          Ответить
        • Это квака, всего 2к строк.
          https://github.com/grayj/Jedi-Academy/blob/master/codemp/game/bg_pmove.c
          Ответить
    • >while ( condition )
      Зачем внутренние пробелы?
      Ответить
      • Стиль такой.
        Ответить
        • Это ответ на "почему" а не "зачем".
          Ответить
          • а вы не думали, что это может быть корпоративные правила форматирования кода?
            с Яндексом например есть такая история http://habrahabr.ru/post/220229/
            Ответить
            • Не думали, так как в моей конторе нет такой хуиты, и это здорово.
              Ответить
              • > в моей конторе нет такой хуиты
                Кто как хочет, так и дрочит? Ну повезло, значит, что весь отдел сплошь единомышленники, и безо всяких дурацких стайл гайдов пишут одинаково...
                Ответить
                • >Ну повезло, значит, что весь отдел сплошь единомышленники, и безо всяких дурацких стайл гайдов пишут одинаково...
                  Ну да, т.к. отдел состоит из одного программиста и железячника.
                  Ответить
                  • > это здорово
                    > отдел состоит из одного программиста и железячника

                    Кмк, в чуть большей команде работать веселее. Ну и я всегда обоими руками за гайдлайны (даже которые мне не совсем по душе), если только они автоматически проверяются.
                    Ответить
                    • А откровенно идиотские гайдлайны типа "X spaces per tab" или "только for loop" вас не смущают?
                      Ответить
                      • > откровенно идиотские гайдлайны
                        > X spaces per tab
                        Нормальный гайдлайн. По крайней мере у всех одинаково показывается, и бесполезных холиваров не будет. А то у нас в конторе есть олдфаг, который любит делать инденты с шагом 3(!) пробела.

                        > только for loop
                        А вот это - и правда идиотский.
                        Ответить
                        • >А то у нас в конторе есть олдфаг, который любит делать инденты с шагом 3(!) пробела.
                          Расстрелять.
                          Ответить
                          • Как можно вообще табулировать пробелами??? Нужно быть супер-мега извращенцем (слепым вдобавок), чтобы жать пробел, когда совсем рядом под пальцами призывно белеет клавиша TAB.
                            Ответить
                            • Достаточно настроить редактор так, чтобы нажатие на TAB отступало на 3 пробела, а не на 4.

                              Кэп.
                              Ответить
                              • А знаешь ли ты, дорогой товарищ, что с каждым пробелом, поставленным тобой, из лысины Штрауструпа выпадает волосок?
                                Ответить
                                • Может ли у трупа быть отрицательно количество волос и что надо сделать, чтобы он полысел?
                                  Ответить
                            • set tabstop=4, ЕМНИП
                              Ответить
                            • * код выглядит одинаково у всех читателей
                              * не надо думать, где ставить какой разделитель - где пробелы, где табы, где их кобенация - везде ставим пробелы и ничего у других читателей не бомбанёт
                              \tvar x = 3,
                              \t    y = 5;

                              * строка у всех влезает в N символов, это N определяется однозначно

                              На практике табы нещадно мешают с пробелами, или не мешают там, где надобно мешать, отчего вся универсальность обычно того же порядка, что и кроссплатформенность в .NET. "Пожалуйста, поставьте ширину в 4 символа, иначе всё расползается". Надо либо обучить людей искусству использования этого символа, либо заменить его понятным и предсказуемым пробелом.
                              Ответить
                              • Вот поэтому, если меня не ограничивает существующий стиль, я настраиваю редактор так: индент 4 символа, таб 8 символов, сохранять табы как пробелы.
                                Ответить
                              • Мда... Вам нужен тролль. Хороший тролль.
                                Помните, как лего было на душе после моих визитов ? Словно бы шлюха забежала в монастырь...
                                А сейчас Вы кисните, как монахи, Тараканьего монастыря. Аскеза хороша, спору нет, но она ведёт к гомосексуализму. Да и скушно...
                                Ответить
                                • О, Вы пришли, чтобы порекомендовать нам полонез Огинского?
                                  Ответить
                                  • Отнюдь. Я не вернусь, в ближайшие 3-4 года, следовательно, полонез Огинского неуместен.

                                    А вот лично Вам, раз уж Вы затронули тему музыки, посоветую вот что (слушать до конца!):

                                    https://www.youtube.com/watch?v=vHx5r9gy7uA
                                    Ответить
                                • bugmenot?
                                  Ответить
                                  • >bugmenot?
                                    Не оскверняйте память о нём. Энто пишет стретор или какой-другой унылый вайпер типа конардо.
                                    Ответить
                                    • Напомните о корнадо?
                                      Ответить
                                      • Давний пациент. Буйный. Представляется мощным русским конём, мечтает о ребёнке-кентавре, предлагает лакнуть яйца и по-другому издевается над русским языком.

                                        Можно быстро вспомнить/понять, кто такой конардо:
                                        http://govnokod.ru/14542#comment216600
                                        http://govnokod.ru/14547#comment216671
                                        http://govnokod.ru/14550#comment216735
                                        http://govnokod.ru/14552#comment216853
                                        http://govnokod.ru/14802#comment218568
                                        http://govnokod.ru/14459#comment214493
                                        Ответить
                              • >отчего вся универсальность обычно того же порядка, что и кроссплатформенность в python
                                Пофиксил
                                Ответить
              • У вас нет единого кодстайла?

                ктоТоПишетТак, КтоТоТак, а_ктото_и_вовсе_так
                Ответить
                • anekotoruetak
                  Ответить
                • все_пишут_как_надо_ибо_Р_чи_так_приказал .

                  Только один пидорас в другом отделе грешит Йодой и многовложенными if'ами на полэкрана по горизонтали, но я его отучу.
                  Ответить
                  • >>в другом отделе грешит Йодой и многовложенными if'ами на полэкрана по горизонтали
                    Инджой йоур Сишка.
                    По-моему, тот человек уже набил достаточно шишек чтоб писать именно так.
                    Ответить
                    • >уже набил достаточно шишек в детстве чтоб писать именно так.
                      fixed
                      Ответить
                    • >Инджой йоур Сишка.
                      Я уже говорил что Йода языка не зависит от.

                      А многовложенные ифы надо рефакторить в:
                      if (!condition1)
                      return false;
                      if (!condition2)
                      return false;
                      // etc
                      // do your stuff
                      return true;

                      Чтобы легче было читать и меинтейнить код.
                      Ответить
                      • Адепты секты одновозвратническва с тобой не согласятся...
                        Ответить
                        • Адепты секты удобочитаемости несогласны с адептами секты неудобочитаемости.
                          Ответить
                      • >Я уже говорил что Йода языка не зависит от.
                        А я уже гойворил, что в языке без неявной конверсии переменных любого типа в условиях к булу, а также уродского присваивания, которое возвращает значение, Йода просто не нужен.
                        Ответить
                        • Ви таки действительно считаете что проблема в языке а не в голове "пгоргаммиста"?
                          Ответить
                          • Таки да. Язык и компилятор по мере сил должны помогать программисту отлавливать ошибки, а не своей уёбищностью побуждать допускать их.
                            Я даже где-то в серъезных апын-сорсных проектах видел эти детские проёбы с =.
                            Ответить
                            • Я даже в коде яблочной tls библиотеки видел
                              if ()
                                  return success;
                                  return success;

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

                        А теперь - более рационалистический подход к вопросу. Алгоритмы оптимизирующих компиляторов очень сложные. В прямом смысле этого слова, k-CFA (k-call site Control Flow Analysis) для функциональных языков - сверхэкспоненциальной сложности и для императивных - полиномиальной сложности. О чем это нам говорит? - О том, что читать код (т.е. читать и понимать - именно то, что должен делать оптимизирующий компилятор), это в общем случае архисложная задача.
                        Дальше - k-CFA работает с графом состоящим из т.н. блоков кода. Блок кода - это набор инструкций, между которыми нет переходов вне этого блока. Соответственно, чем меньше таких блоков инструкций, тем проще понять такую програму!
                        Другими словами, когда мы добавляем лишний return, мы делаем код более сложным для понимания (потому что у нас уже есть определение того, что такое понимание, и его количественное выражение!).

                        Что касается поддержки - конечно, для того, если чтобы проследить доходит ли выполнение до конца функции, в нее нужно поставить несколько бряков, лучше, чем когда нужно поставить только один. Это же очевидно.

                        Противоречие возникает на самом деле изза того что:

                        1. Привычка (иррациональное предпочтение более знакомого менее знакомому).
                        2. Лень (желание писать много вложеных ифов, потму что лень создать отдельную процедуру).
                        Ответить
                        • Спасибо за просвещение, но мы говорим о простоте понимания для человека, а не компилятора.

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

                              You may now enlighten me.
                              Ответить
                              • Эту теорию изобрел не кто иной, как Алан Тьюринг. Эта теория описывает как любой рациональный агент (в том числе человек и компьютер) производят вычисления. Именно базируясь на этой теории мы рассчитывам сложность чего бы то ни было.

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

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

                                Привычка делает некоторые операции более быстрыми (т.е. привычка работает в чем-то похоже на кеш процессора, делая некоторые операции более доступными). Но привычка так же не дает дать универсальную оценку. Если требуется установить на сколько сложно Х для любого человека в оптимальных условиях, то нам нужно предполагать, что привычки не влияют на вычисления (другими словами, нужно предполагать, что нужную привычку можно максимально развить).
                                Ответить
                            • Некоторые считают, что человек способен решать задачи, неразрешимые компьютером.
                              Пенроуз, например.
                              Ответить
                              • Я читал только критику Пенроуза (у Хофстадтера), и мне тяжело даже представить, что эти сомнения правомерны, а не просто неправильная интерпретация Тьюринга.
                                Ответить
                              • > человек способен решать задачи, неразрешимые компьютером
                                Ultimate CAPTCHA.
                                Ответить
                                • "Will the following code halt on any input?"
                                  Ответить
                                  • > Will the following code halt on any input?
                                    И человек и бот пройдут с вероятностью 1/2.
                                    Ответить
                                    • Так сделаем 4 теста подряд: Will the following code halt on the given input?

                                      Вероятность 1/16.
                                      Ответить
                                      • > Вероятность 1/16.
                                        И у человека и у робота? :)
                                        Ответить
                            • >Что навело вас на мысль, что компилятор понимает код програмы каким-то другим (худшим или лучшим?) способом?

                              Когда компилятор разбирает код программы, он должен проанализировать все варианты хода исполнения. Когда разбирает человек - в большинстве случаев ему важны только некоторые из них. А всякие редкие ситации "не найден файл", "функция API вернула 0" ему не нужны.

                              На этом, например, исключения построены - не загромождать код лишними проверками. С ретурнами та же ситуация - мы увидели что при таких-то событиях выполнение функции прерывается и все. То, что конкретно означает это "прерывание" и что это будет означать - нам (в большинстве случаев неинтересно).
                              Поэтому, ставя return или используя исключения мы идем на компромис - упрощаем чтение нормального хода исполнения, но возможно усложняем анализ редкого ненормального.
                              Ответить
                              • Если програмист не поймет все варианты, то как же это можно назвать "понял"? Это не понял, это "почувствовал".

                                Чем исключение для програмиста отличается от исключения для компилятора?

                                Нет, мы ничего не упрощаем добавляя return. Предыдущая тирада ничего не говорит в пользу простоты или сложности. Она вообще ни про сложность ни про простоту не говорит. Вам кажется что вы что-то упрощаете? А мне не кажется, и что теперь?
                                Ответить
                                • >Чем исключение для програмиста отличается от исключения для компилятора?

                                  Ладно, простой вопрос. Исключения же - переход из блока. Любая функция потенциально может их содержать. Т.е. по вашей логике любая программа на языке с исключениями получается намного более сложной для чтения (даже если сам текст не изменился). Я правильно понимаю?
                                  Ответить
                                  • Нет, не правильно. Мера сложности програмы - количество арк в ее контрол-флоу / дата-флоу графе.

                                    Другими словами: сложность или простота - это численная характеристика системы, на основе которой можно сравнить два экземпляра системы, и сказать, в каком из них меньше (или больше) этой характеристики.
                                    Примеры, когда можно говорить о простоте / сложности: один экземпляр состоит из Х частей, а другой - из Х - 1 частей, т.о. можно говорить, что второй - проще. Либо, можно посмотреть на эту характеристику как на потенциальные возможности экземпляра. Т.е. один экземпляр может произвести Х других частей, а другой - Х * 2, и тогда второй - более сложный.

                                    Но я не вижу в каком смысле добавление сущностей упрощает тут что-то. Когда я пытаюсь выяснить мотивацию людей, которые так поступают, то я всегда, без исключений, сталкиваюсь с ответами:
                                    1. Я так привык.
                                    2. Я лентяй (мне жалко времени на то, чтобы вынести код в отдельную процедуру).
                                    3. Оно само.
                                    4. В очень редких случаях (плохой компилятор) несколько точек возврата может работать быстрее одной точки возврата.
                                    Ответить
                                    • >Нет, не правильно. Мера сложности програмы - количество арк в ее контрол-флоу / дата-флоу графе.

                                      И? Вот я беру сишную процедуру, в ней X "арок". Теперь компилирую ее в С++ (и теперь каждая из вызываемых процедур может вызвать исключение и прервать ее исполнение). Арок добавилось и немало (или исключения почему-то в нашем графе не рассматриваются? Но это же нематематично). Процедура стала сложнее для чтения?
                                      Ответить
                                      • А ретурны - это такие "исключения для бедных", чтобы тоже один раз написать return и дальше уже не заморачиваться, даже если заморочка выражается в лишнем отступе и паре скобок. Соответственно если я в целом доверяю коду (или там выше ретурном ничего сложного нет), я не буду следить нет ли там потекших указателей из-за этого ретурна и буду читать код как если бы никакого ретурна не было. А компилятор "доверять" коду не может, поэтому для него может стало сложнее (хотя для него обе формы вообще эквививалентны, что ретурн, что фигурные скобки на всю оставшуюся функцию).
                                        Ответить
                                        • Кстати, ещё ж у нас есть абстракции и инкапсуляция.
                                          Можно не доверять коду, но использовать как минимум std::map<std::string, my_type>, мыслить в этих терминах, не затуманивая себе голову тем, во что шаблоны развернутся и сколько будет страдать компилятор.
                                          Ответить
                                        • Мы только что выяснили, что обе конструкции не эквивалентны (количество арок разное), но возможно преобразование (и даже желательно, потому что в варианте с лишним return, return - лишний).

                                          Если вы "доверяете", "чувствуете", "надеетесь" и т.д. - это не значит "понимаете". Но вопрос только о понимании. Остальные ваши духовные переживания не влияют на суть вопроса.
                                          Ответить
                                      • Нет, ничего не изменится после компиляции одного в другое. Если ошибки возможны, то они уже описаны в этой програме. По определению блока, возможность ошибки = выход из блока.

                                        Что такое "нематематично"?

                                        http://en.wikipedia.org/wiki/Basic_block
                                        Вот тут описано что такое блок (и, вчасности, говорится про ошибки):
                                        Instructions that end a basic block include the following:

                                        unconditional and conditional branches, both direct and indirect
                                        returns to a calling procedure
                                        instructions which may throw an exception
                                        function calls can be at the end of a basic block if they cannot return, such as functions which throw exceptions or special calls like C's longjmp and exit
                                        the return instruction itself.
                                        Ответить
                                        • >unconditional and conditional branches, both direct and indirect
                                          > returns to a calling procedure
                                          >instructions which may throw an exception

                                          Ну т.е. что return посреди блока, что функция которая может бросить исключение посреди блока - никакой разницы.

                                          >Нет, ничего не изменится после компиляции одного в другое. Если ошибки возможны, то они уже описаны в этой програме.

                                          Еще раз, есть процедура { int x = a(); b(x);}
                                          Мы компилируем ее сначала в С, потом в С++. Во втором случае в а() может произойти исключение, в первом - всегда будет вызвана b (просто ей будет передан x свидетельствующий об ошибке, например нулевой). Изменилась ли сложность чтения? И как эта сложность соотносится с { int x = a(); if(!x) return; b(x);} и { int x = a(); if(x) b(x);}
                                          Ответить
                                          • Прочитайте статью по ссылке, может дойдет. Я, очевидно, не специалист в объяснениях.
                                            Ответить
                                            • Вы ответить на вопрос можете? Или я не специалист в задавании вопросов?
                                              Ответить
                                              • Ваш вопрос свидетельствует о невладении необходимой номенклатурой для понимания ответов.

                                                Две програмы приведенные вами - это разные програмы, и имеют разный смысл. Естесственно, что и сложность у них будет разная. А представляете, у этой же програмы есть еще и какой-то смысл на J, в качестве регулярного выражения и т.д., и, более того, поскольку это фрагмент програмы, а не вся програма, то я могу даже предположить, что это фрагмент, например, такой програмы:
                                                console.log("{ int x = a(); b(x);}");
                                                - и буду прав.
                                                Ответить
                                                • >Ваш вопрос свидетельствует о невладении необходимой номенклатурой для понимания ответов.
                                                  Будем считать это "да", сложность изменилась когда мы допустили исключения.

                                                  > Естесственно, что и сложность у них будет разная.
                                                  Угу.

                                                  А при чтении - первые две воспринимаются одинаково, насчет двух вторых можно поспорить. И да, при чем тут "вся программа", я говорил о процедурах.
                                                  Так что можно считать доказанным, что человек читает тексты программ иначе, чем компилятор. Ну, или ваше понимание "сложности чтения" отличается от нормального.
                                                  Ответить
                                                  • Нет, сложность не изменилась и не не изменилась. Мы сначала рассматривали одну програму, а потом другую, (на разных языках!) которые случайно выглядят одинаково. Из этого вообще никаких вывыдов делать нельзя, потому что это не относится к теме разговора.
                                                    Ответить
    • > for ( i=0 ; i<3 ; i++ ) {
      i<3quake
      Ответить
    • Комментарии, комментарии-то...
      // Need to avoid nesting namespaces!
      #include "../namespace_end.h"
      #ifdef QAGAME //including game headers on cgame is FORBIDDEN ^_^
      
      #include "g_local.h"
      extern void NPC_SetAnim(gentity_t *ent, int setAnimParts, int anim, int setAnimFlags);
      extern gentity_t g_entities[];
      
      #elif defined CGAME
      
      #include "..\cgame\cg_local.h" //ahahahahhahahaha@$!$!
      
      #endif
      #include "../namespace_begin.h"
      Ответить

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