- 1
- 2
// bg_pmove.c -- both games player movement code
// takes a playerstate and a usercmd as input and returns a modifed playerstate
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+131
// bg_pmove.c -- both games player movement code
// takes a playerstate and a usercmd as input and returns a modifed playerstate
Дальше идут 11 тысяч строк нечитаемого говна. Это вообще нормально?!
И тут вдруг в сети оказались исходники кваки!
Но некоторые люди умудряются в своем профессиональном развитии иметь отрицательный возраст.
http://govnokod.ru/9903
https://github.com/grayj/Jedi-Academy/blob/master/codemp/game/bg_pmove.c
Зачем внутренние пробелы?
с Яндексом например есть такая история http://habrahabr.ru/post/220229/
Кто как хочет, так и дрочит? Ну повезло, значит, что весь отдел сплошь единомышленники, и безо всяких дурацких стайл гайдов пишут одинаково...
Ну да, т.к. отдел состоит из одного программиста и железячника.
> отдел состоит из одного программиста и железячника
Кмк, в чуть большей команде работать веселее. Ну и я всегда обоими руками за гайдлайны (даже которые мне не совсем по душе), если только они автоматически проверяются.
> X spaces per tab
Нормальный гайдлайн. По крайней мере у всех одинаково показывается, и бесполезных холиваров не будет. А то у нас в конторе есть олдфаг, который любит делать инденты с шагом 3(!) пробела.
> только for loop
А вот это - и правда идиотский.
Расстрелять.
Кэп.
* не надо думать, где ставить какой разделитель - где пробелы, где табы, где их кобенация - везде ставим пробелы и ничего у других читателей не бомбанёт
* строка у всех влезает в N символов, это N определяется однозначно
На практике табы нещадно мешают с пробелами, или не мешают там, где надобно мешать, отчего вся универсальность обычно того же порядка, что и кроссплатформенность в .NET. "Пожалуйста, поставьте ширину в 4 символа, иначе всё расползается". Надо либо обучить людей искусству использования этого символа, либо заменить его понятным и предсказуемым пробелом.
Помните, как лего было на душе после моих визитов ? Словно бы шлюха забежала в монастырь...
А сейчас Вы кисните, как монахи, Тараканьего монастыря. Аскеза хороша, спору нет, но она ведёт к гомосексуализму. Да и скушно...
А вот лично Вам, раз уж Вы затронули тему музыки, посоветую вот что (слушать до конца!):
Не оскверняйте память о нём. Энто пишет стретор или какой-другой унылый вайпер типа конардо.
Можно быстро вспомнить/понять, кто такой конардо:
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
Пофиксил
ктоТоПишетТак, КтоТоТак, а_ктото_и_вовсе_так
HekoTopble
P.S. 7 6uT xBaTuT BceM
Пиздец-то какой!
------
Ха-ха-ха, посмотрю я на нубов если у них не будет ни гугла ни яндекса)
Только один пидорас в другом отделе грешит Йодой и многовложенными if'ами на полэкрана по горизонтали, но я его отучу.
Инджой йоур Сишка.
По-моему, тот человек уже набил достаточно шишек чтоб писать именно так.
fixed
Я уже говорил что Йода языка не зависит от.
А многовложенные ифы надо рефакторить в:
Чтобы легче было читать и меинтейнить код.
А я уже гойворил, что в языке без неявной конверсии переменных любого типа в условиях к булу, а также уродского присваивания, которое возвращает значение, Йода просто не нужен.
Я даже где-то в серъезных апын-сорсных проектах видел эти детские проёбы с =.
Казалось бы, причем тут питон и кто соснул.
А теперь - более рационалистический подход к вопросу. Алгоритмы оптимизирующих компиляторов очень сложные. В прямом смысле этого слова, k-CFA (k-call site Control Flow Analysis) для функциональных языков - сверхэкспоненциальной сложности и для императивных - полиномиальной сложности. О чем это нам говорит? - О том, что читать код (т.е. читать и понимать - именно то, что должен делать оптимизирующий компилятор), это в общем случае архисложная задача.
Дальше - k-CFA работает с графом состоящим из т.н. блоков кода. Блок кода - это набор инструкций, между которыми нет переходов вне этого блока. Соответственно, чем меньше таких блоков инструкций, тем проще понять такую програму!
Другими словами, когда мы добавляем лишний return, мы делаем код более сложным для понимания (потому что у нас уже есть определение того, что такое понимание, и его количественное выражение!).
Что касается поддержки - конечно, для того, если чтобы проследить доходит ли выполнение до конца функции, в нее нужно поставить несколько бряков, лучше, чем когда нужно поставить только один. Это же очевидно.
Противоречие возникает на самом деле изза того что:
1. Привычка (иррациональное предпочтение более знакомого менее знакомому).
2. Лень (желание писать много вложеных ифов, потму что лень создать отдельную процедуру).
В случае многовложенных ифов, это просто GBPLTW разбираться в них если на пятом ифе условие уезжает в неведомые ебеня за предел экрана.
Что навело вас на мысль, что компилятор понимает код програмы каким-то другим (худшим или лучшим?) способом?
You may now enlighten me.
Другими словами, универсальная теория вычислений представляет любые вычисления как последовательности атомарных операций. Для того, чтобы дать количественную оценку сложности, мы считаем эти атомарные операции. Т.е. это не важно, будет ли это грузчик на складе сортировать коробки по сроку годности, или это будет компьютер сортировать числа в памяти - сложность будет такой же, при использовании одной и той же процедуры сортировки.
Естесственно, это идеализированая модель, и может так оказаться, что атомарные операции одного вида занимают больше времени, чем атомарные операции другого вида, но в таком случае либо нужно это указывать, либо сложность не будет определена.
Привычка делает некоторые операции более быстрыми (т.е. привычка работает в чем-то похоже на кеш процессора, делая некоторые операции более доступными). Но привычка так же не дает дать универсальную оценку. Если требуется установить на сколько сложно Х для любого человека в оптимальных условиях, то нам нужно предполагать, что привычки не влияют на вычисления (другими словами, нужно предполагать, что нужную привычку можно максимально развить).
Пенроуз, например.
Ultimate CAPTCHA.
И человек и бот пройдут с вероятностью 1/2.
Вероятность 1/16.
И у человека и у робота? :)
Когда компилятор разбирает код программы, он должен проанализировать все варианты хода исполнения. Когда разбирает человек - в большинстве случаев ему важны только некоторые из них. А всякие редкие ситации "не найден файл", "функция API вернула 0" ему не нужны.
На этом, например, исключения построены - не загромождать код лишними проверками. С ретурнами та же ситуация - мы увидели что при таких-то событиях выполнение функции прерывается и все. То, что конкретно означает это "прерывание" и что это будет означать - нам (в большинстве случаев неинтересно).
Поэтому, ставя return или используя исключения мы идем на компромис - упрощаем чтение нормального хода исполнения, но возможно усложняем анализ редкого ненормального.
Чем исключение для програмиста отличается от исключения для компилятора?
Нет, мы ничего не упрощаем добавляя return. Предыдущая тирада ничего не говорит в пользу простоты или сложности. Она вообще ни про сложность ни про простоту не говорит. Вам кажется что вы что-то упрощаете? А мне не кажется, и что теперь?
Ладно, простой вопрос. Исключения же - переход из блока. Любая функция потенциально может их содержать. Т.е. по вашей логике любая программа на языке с исключениями получается намного более сложной для чтения (даже если сам текст не изменился). Я правильно понимаю?
Другими словами: сложность или простота - это численная характеристика системы, на основе которой можно сравнить два экземпляра системы, и сказать, в каком из них меньше (или больше) этой характеристики.
Примеры, когда можно говорить о простоте / сложности: один экземпляр состоит из Х частей, а другой - из Х - 1 частей, т.о. можно говорить, что второй - проще. Либо, можно посмотреть на эту характеристику как на потенциальные возможности экземпляра. Т.е. один экземпляр может произвести Х других частей, а другой - Х * 2, и тогда второй - более сложный.
Но я не вижу в каком смысле добавление сущностей упрощает тут что-то. Когда я пытаюсь выяснить мотивацию людей, которые так поступают, то я всегда, без исключений, сталкиваюсь с ответами:
1. Я так привык.
2. Я лентяй (мне жалко времени на то, чтобы вынести код в отдельную процедуру).
3. Оно само.
4. В очень редких случаях (плохой компилятор) несколько точек возврата может работать быстрее одной точки возврата.
И? Вот я беру сишную процедуру, в ней X "арок". Теперь компилирую ее в С++ (и теперь каждая из вызываемых процедур может вызвать исключение и прервать ее исполнение). Арок добавилось и немало (или исключения почему-то в нашем графе не рассматриваются? Но это же нематематично). Процедура стала сложнее для чтения?
Можно не доверять коду, но использовать как минимум std::map<std::string, my_type>, мыслить в этих терминах, не затуманивая себе голову тем, во что шаблоны развернутся и сколько будет страдать компилятор.
Если вы "доверяете", "чувствуете", "надеетесь" и т.д. - это не значит "понимаете". Но вопрос только о понимании. Остальные ваши духовные переживания не влияют на суть вопроса.
Что такое "нематематично"?
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.
> 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, в качестве регулярного выражения и т.д., и, более того, поскольку это фрагмент програмы, а не вся програма, то я могу даже предположить, что это фрагмент, например, такой програмы: - и буду прав.
Будем считать это "да", сложность изменилась когда мы допустили исключения.
> Естесственно, что и сложность у них будет разная.
Угу.
А при чтении - первые две воспринимаются одинаково, насчет двух вторых можно поспорить. И да, при чем тут "вся программа", я говорил о процедурах.
Так что можно считать доказанным, что человек читает тексты программ иначе, чем компилятор. Ну, или ваше понимание "сложности чтения" отличается от нормального.
i<3quake
Что-за зловещий смех? Видимо из за \ вместо /?
АЗАЗАЗАЗА111