Comments 52
«В редакторе настоящего программиста должна отсутствовать функция копирования блоков [текста]» © Чарльз Мур (?) :)
+21
Да, как люди только ни страдают лишь бы не использовать лисп^Wмакросы и ФП.
+3
Не, серьезно, пора делать постинг ачивок в соцсетях: «30 дней без ошибок в последней строке», «Проект похвалили ребята из PVS-Studio».
Главное, что это не обидно будет, ачивка-то будет об отсутствии косяков, а не об их наличии!
А если серьезно, то крупным проектам прямо хорошим тоном было бы заказывать у вас проверку их трудов — может, вы и не 100% косяков выявите, но сторонним взглядом посмотрите, а то и других статьей научите, все же профит!
Главное, что это не обидно будет, ачивка-то будет об отсутствии косяков, а не об их наличии!
А если серьезно, то крупным проектам прямо хорошим тоном было бы заказывать у вас проверку их трудов — может, вы и не 100% косяков выявите, но сторонним взглядом посмотрите, а то и других статьей научите, все же профит!
+13
Лучше бы, конечно, «ХХ дней без копипасты» :)
+6
Риск получить нештатную ситуацию всегда выше в крайних точках, когда начинаешь и когда заканчиваешь. Я стараюсь про это не забывать в любом деле.
+2
OpenSSL… Длина строки «BITLIST» не 3, а 7 символов...
Меня это настораживает — там уже где то был баг где длина буфера неправильная была :)
+12
Меньше — не больше… Да и операция сравнения несколько безопаснее операции чтения блока памяти.
+1
Эээ… А чем сравнение не чтение?
0
Ага, особенно прикольно сравнить меньше символов где-нибудь в checksum :-)
И понизить криптостойкость на несколько порядков.
И понизить криптостойкость на несколько порядков.
0
Глупый вопрос: как вообще это всё работает? Вы уже немало статей написали с явными ошибками. Не синтаксическими, а логическими. Если их ещё не исправили, значит они не заметны и программа вроде как работает. Почему? Ведь надёжность сложной системы, составленной из блоков, меньше, чем сумма надёжностей этих блоков?
+9
Едет ли машина у которой не горят фары?
+56
Весьма краткий и точный ответ. :)
+12
Самое отвратительное даже не то, что она едет, а что если ездить только днём то даже не узнаешь, что с ней что-то не так.
+34
В нормальных машинах есть индикаторы, которые оповещают водителя о проблемах, в том числе о перегоревших (не горящих) фарах. Такой же эффект принесут юнит-тесты в разрабатываемом приложении.
-3
Наличие тестов тоже не гарантия: Как статический анализ дополняет TDD :).
А некоторые вещи вообще юнит-тестами поймать практически невозможно: V596, V597.
А некоторые вещи вообще юнит-тестами поймать практически невозможно: V596, V597.
+4
Вот 596й не совсем правильный пример — хорошие тесты должны покрывать и «плохие» случаи тоже. Отсутствие искдючения -> тест провален.
А вот 597й да, плохо. При сборке тестов если проверять на чистоту на выходе — оптимизатор не выкинет memset; а в релизе может и выкинуть.
А вот 597й да, плохо. При сборке тестов если проверять на чистоту на выходе — оптимизатор не выкинет memset; а в релизе может и выкинуть.
0
На практике 596 покрыть крайне сложно и никто это не делает. Что-бы в нужный момент new кинул исключение, нужна целая система.
0
А как же «ни коммита без 100% покрытия»?
0
Это в параллельной вселенной. На практике, даже в те, кто стараются, обычно покрывают только 80%.
+2
Кроме того, при желании не сложно обеспечить формально 100% (или близко к этому) покрытия тестами, которые по сути не особо полезны — то, что строчка кода выполнилась в процессе работы теста не даёт гарантии, что вся функциональность и все возможные случаи действительно были протестированы. Так что «покрытие» полезно только тем, что показывает какой код точно не тестируется, но ничего полезного не говорит про качество тестирования покрытого кода.
+3
Что значит «в нормальных»? Где эта норма? Я повидал с десяток машин разной стоимости — от 300 тысяч до более миллиона. И только в одной есть датчик неработающих фар.
+2
Веет дао :-)
-1
По себе могу сказать — иногда просто везет. Например, по милости компилятора (или согласно своей-же крюкописи где-то в другом месте в коде) переменная, которой сам забыл присвоить значение (как, например, здесь: pattern->patternRepeatY = false;), уже содержит нужное значение. Ошибку-то ты потом сам находишь, но только по коду, а в работе программы она не проявляется. Вот так и живем. ))
0
А есть статистика, сколько ошибок происходит из-за копипасты по сравнению с прочими, в процентах от общего кол-ва? Хотя бы примерно.
+1
Хорошо, что анализатора во времена Quake не было, иначе бы ни распрыжки, ни овербаунсов…
+23
Это баги, а не заложенная особенность физики? Про это где-то можно почитать?
0
Вроде бы сначала это были особенности реализации (непреднамеренные), а в последующих версиях такие вещи стали закладывать как фичу, потому что киберспортсмены и любители триксов (распрыжки и тд) привыкли.
+2
Впервые распрыжка появилась в quake 2 как баг, но из-за того, что он сильно вошел в моду, в 3й части его сделали фичей. Другой баг — двойной прыжок (double jump) был «исправлен», однако появился новый — overbounce, ситуация, когда при столкновении с поверхностью вектор скорости отражался либо в противоположную сторону, либо в другую плоскость. Распрыжка была переполнением, в 2000х был блог у разработчиков промода, они там это описывали. Сейчас только гуглить остается.
+2
Ну здрасте! Распрыжка появилась ещё в Quake I, а с физикой QuakeWorld получила всеобщее распространение. Самая круть была в Quake TF ворваться на базу врага разогнанным heavy guy с 300 красной броней на скорости в 1000 единиц и пролететь сквозь взрывающиеся поля и гранаты, забрать флаг и унестись к себе на базу =)
0
Я где-то слышал, что часто альпинисты срываются на последних десятках метрах подъема. Не потому, что они устали. Просто они радуются, что осталось совсем немного. Они предвкушают сладкий вкус победы над вершиной. В результате они ослабляют внимание и допускают роковую ошибку.
Я в Super Hexagon так играю. Проигрываю часто на плюс-минус 00:59.50 (там одна минута — «победа»).
+3
ContainerEndLine != ContaineeEndLineЗа такие названия переменных нужно бить по рукам. Различие в одну букву в середине слова совершенно не видно при беглом чтении кода. Да что там, чтобы это заметить даже при внимательном чтении, мне пришлось сравнивать названия переменных побуквенно!
+4
UFO just landed and posted this here
Я сразу заметил разницу. Мне они даже не показались похожими.
P.S. Я много читаю и привык глотать слова целиком, всегда замечаю отличие даже в одну букву
P.S. Я много читаю и привык глотать слова целиком, всегда замечаю отличие даже в одну букву
0
Видимо, это код писал человек, подобный вам )
P.S. Я много читаю и привык глотать слова целиком, не замечая ошибок в одной букве…
P.S. Я много читаю и привык глотать слова целиком, не замечая ошибок в одной букве…
+4
Ну значит нужно ещё и словарный запас подтянуть. *er vs *ee — это довольно частая фишка в английском. Contrainer vs Containee, Employer vs Employee и т.д. и т.п. Путать их ни в коем случае нельзя. Да и какая тут «середина слова» к бесу? Это ж последняя буква! Тут скорее камешек в огород CamelCaseIdentifiers…
0
Словарный запас тут ни при чём, я знаю об *er и *ee. Мы сейчас работаем над поддержкой WebRTC в нашем приложении, и было бы логично назвать звонящего Caller, а отвечающего — Callee. Но не всё то, что логично, ещё и удобно. На слух слова указанными выше окончаниями чётко различимы, тогда как при чтении ошибиться очень легко, а при написании — и подавно: латинские буквы E и R расположены на клавиатуре рядом. В результате мы вообще не стали использовать слово Callee, и, т.к. в коде нужно только знать, кто инициировал звонок, назвали звонящего initiator. Всё-таки, мы заботимся, по возможности, о читающих наш код коллегах.
Про середину слова вы заметили верно, но, по сути, просто придрались к словам (нечаянный каламбур), т.к. буквы различаются в середине идентификатора. Великая разница.
И CamelCase тут не виноват. Вот это
Про середину слова вы заметили верно, но, по сути, просто придрались к словам (нечаянный каламбур), т.к. буквы различаются в середине идентификатора. Великая разница.
И CamelCase тут не виноват. Вот это
container_end_line != containee_end_line
не очень сильно улучшает читабельность кода. Я искренне рад за вас, раз вы обладаете способностью мгновенно обнаруживать подобные отличия в одну букву, но увы, я и множество (не в математическом смысле) других людей обделены этим даром. Выбирать чётко различимые названия переменных — одно из правил хорошего тона в разработке ПО.+1
Будучи перфекционистом, давно, еще в ВУЗе заметил, что очень часто ошибаюсь при копи-пастинге.
Очень скоро стало жалко тратить время на отладку и поиск «детских» ошибок и была выработана методика по «недопущению» таких ошибок.
Поделюсь, может кому-нибудь сбережет немного времени и нервов.
Звучит сложно, на по факту, все делается быстро и почти на автомате.
Для наглядности рассмотрим пример. Есть код (из примеров выше):
Я бы писал так:
Получаем исходный акроним (восьмая колонка): xyz.
Получаем остальные акронимы: xyy, xyz.
Опечатка более-менее видна.
В указанной методике важны все 4 пункта. Они дополняют друг-друга.
Отсутствие любого из пунктов или сводит на нет эффективность, или приводит к неврозу «все ли копи-пасты проверены».
Очень скоро стало жалко тратить время на отладку и поиск «детских» ошибок и была выработана методика по «недопущению» таких ошибок.
Поделюсь, может кому-нибудь сбережет немного времени и нервов.
— Как только нажали Ctrl+C, выставляем (в уме или лучше в комментах) флаг «копи-паста»: //CP->
— Пишем копи-пасту НАРУШАЯ ВСЕ правила форматирования кода — главное чтоб отличающиеся места были в одной колонке.
— Закончив редактирование копи-пасты, составляем и сверяем акронимы отличающихся колонок слева и справа (если несколько, то все).
— Только после того как убедились, что все верно, снимаем флаг копи-пасты. Но в коде, в комментах, оставляем метку копипасты: //CP
Звучит сложно, на по факту, все делается быстро и почти на автомате.
Для наглядности рассмотрим пример. Есть код (из примеров выше):
intens.x=OrSIMD(AndSIMD(BackgroundColor.x,no_hit_mask),
AndNotSIMD(no_hit_mask,intens.x));
intens.y=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
AndNotSIMD(no_hit_mask,intens.y));
intens.z=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
AndNotSIMD(no_hit_mask,intens.z));
Я бы писал так:
intens.x = OrSIMD(AndSIMD(BackgroundColor.x, no_hit_mask), AndNotSIMD(no_hit_mask, intens.x));
intens.y = OrSIMD(AndSIMD(BackgroundColor.y, no_hit_mask), AndNotSIMD(no_hit_mask, intens.y));
intens.z = OrSIMD(AndSIMD(BackgroundColor.y, no_hit_mask), AndNotSIMD(no_hit_mask, intens.z));
Получаем исходный акроним (восьмая колонка): xyz.
Получаем остальные акронимы: xyy, xyz.
Опечатка более-менее видна.
В указанной методике важны все 4 пункта. Они дополняют друг-друга.
Отсутствие любого из пунктов или сводит на нет эффективность, или приводит к неврозу «все ли копи-пасты проверены».
+3
Good. Я про аналогичное писал здесь "Последствия использования технологии Copy-Paste при программировании на Си++ и как с этим быть".
+1
У меня какая то другая тенденция, при копипасте скорее во втором пункте ошибусь, чем в последнем)
0
Эклипс подсказывает, а не копипастная ли ошибка.
0
Моё новое интересное исследование: Зло живёт в функциях сравнения.
+1
Данная статья относится к серии «ужасы для программистов». Продолжаю эту тематику и предлагаю почитать: Ноль, один, два, Фредди заберёт тебя.
0
Sign up to leave a comment.
Эффект последней строки