Goto
Нередко в разговорах программистов всплывает тема оператора «goto». Например, сообщество крупно побурлило после появления его в ПХП. Многие считают, что оператор вредный, его появление в языке «понижает» язык в классе до Бейсика (хотя современные Бейсики — очень мощные языки) и он несёт только вред.
Грустно то, что обычно критики предоставляют аргументы на уровне вкусовщины, даже не пытаясь сформулировать аргументы, видимо считая, что уровень «плохо, потому что goto» достаточен.
Попробую возразить.
С последним аргументам в спорах обычно не соглашаются, говорят, что goto как правило умеет больше, чем эта пара операторов. Тут надо отступить и вспомнить чем вообще был плох обсуждаемый оператор.
Плох он, вообще говоря,
Так вот, всего этого современный оператор просто не умеет. Современный goto — тёзка того старого, плохого, сейчас он умеет переходить на метку, но не на всякую, а с огромным количеством ограничений и его использование не более вредно или стыдно, чем использование break или continue.
Комментарии 19
Что может привести к ещё большей запутанности кода, чем даже с goto.
Кстати, напишите мне поиск указанного элемента массива без break.
«Это плохо, ужасно плохо», а что именно плохо -- загадка.
Ничего плохого в гото нет. Да, его использование может усложнить код.
Но в редких ситуациях именно он может секономить много времени и кода.
goto — это jump в чистом виде.
break/continue — это первая производная от goto, jump с кучей проверок.
try/catch/throw/finally — опять всё то же самое goto, только уже с объектным душком и всякими рюшечками. но всё равно всё сводится к банальному jump.
да ведь, в конце концов, return это оно же самое. возврат на стек, регистры восстановить, а потом — jump. но только почему никто не говорит, что return это плохо, и его надо выпилить? чё народ так
break и continue — скорее не goto с кучей проверок, а оператор, работающий единственно возможным способом. И их можно рассматривать не как goto, а как синтаксический сахар для if/else с дополнительными переменными.
Вместо break — добавляем условие цикла:
http://pastebin.com/ZM75jLzK
Я ещё return забыл — это тоже разновидность goto.
А вот try…catch — это goto технически, но не по смыслу. Их смысл — не в переходе в другое место программы, а в аварийной передаче управления.
Т.е. цикл каждую итерацию теперь проверяет ещё одно, совершенно ненужное условие? Плохое решение. Но, вы, смотрю, не специалист в программировании. is_null (функция) вместо === null (конструкция), count, вычисляемый в каждую итерацию цикла.
В общем, у вас простительные заблуждения.
Комментарий для Евгения Степанищева:
зачем так? некрасиво же. то что в тестовом примере у человека count вычисляется каждую итерацию, не делает его автоматически неправым во всех остальных утверждениях. правым впрочем тоже.
Комментарий для Евгения Степанищева:
А с использованием break он не будет проверять его каждый раз перед break? Можно в цикле просто получать элемент в переменную, а в условии проверять, она это или нет, будет по одной проверке на цикл.
Ну и, в любом случае, эта break тут помогает код организовать, избавление от лишнего вызова асимптотически ни на что не влияет, да и, скорее всего, будет преждевременной оптимизацией.
Комментарий для fulc.ru:
Да, тут я промахнулся.
Не путай качество кода и преждевременную оптимизацию. То, что оптимизация не должна быть преждевременной не говорит о том, что код надо писать плохо.
Работал пару лет назад в компании, в которой очень сильно следили за качеством кода, поэтому были огромные своды правил, как с точки зрения аккуратности кода (4 пробела вместо табов, отсутствие лишних пробелов в инструкциях или наличие таковых для удобочитаемости, и т.д.), так и с технической точки зрения (не использовать goto, continue, break, и т.д.).
Однако, всё время в компании ходят споры о том, почему это нельзя делать: никто доводов толковых не приводил. Я сам об этом читал в книгах, вроде МакКоннел «Совершенный код», и т.д.
Везде один довод: «запутанность кода». Однако при правильном разбиении кода на методы и нормальной архитектуре,
И вот, читая интереснейший цикл статей «Что каждый программист должен знать о памяти» я нарвался на доступное объяснение чем плох любой переход (JUMP) с точки зрения производительности (ссыль http://rus-linux.net/lib.php?name=/MyLDP/h … -3.html%29:
« Код имеет то преимущество, что между переходами он линеен. В такие периоды процессор может эффективно делать предварительную загрузку памяти. Переходы нарушают эту идеальную картину
— цель перехода может быть определена не статически;
— даже если она определена статически, загрузка памяти может занять длительное время, если эта цель отсутствует во всех кэшах.
Эти проблемы создают задержки при выполнении кода с возможным существенным снижением производительности.»