Подписка на блог

В Телеграме помимо ссылок на заметки делюсь околодизайнерскими наблюдениями.

В Твиттере помимо ссылок на заметки пишу всякую чушь.

В Тумблере и Же-же есть автоматические трансляции. Если не работает, напишите мне: ilyabirman@ilyabirman.ru.

По РСС и Джейсон-фиду трансляции для автоматических читалок

Goto vs. Throw

По-моему то, что goto — это плохо, придумали не очень умные люди. Это дело разработчика, какие управляющие конструкции использовать. Если разработчик плохой, то он и без goto сделает код непонятным, а если хороший, то goto ему поможет сделать код лучше там, где это возможно.

Самое интересное, что когда люди поняли, что goto всё-таки нужен, но уже было слишком распространено мнение, что «им пользуются только лохи», они придумали throw. Причём, замаскировали его так, чтобы сразу трудно было догадаться, что это просто goto переименовали:
  • Сделали синтаксис trycatch (catch — это описание метки, вместо label, а try — просто для симметрии)
  • Придумали красивую легенду про то, что это всё вообще для отлова ошибок, точнее даже «исключительных ситуаций», а вовсе не для того, чтобы вернуть goto народу
  • Привязали это всё к классам, объектам, иерархии, наследованию (добавьте умные слова по вкусу) — чтобы уж совсем сбить людей с толку
Подписаться на блог
Поделиться
Отправить
12 комментариев
Weasel
Если писать код лично для себя, то можно без проблем пользоваться goto, или try/catch вместо goto, и даже try/catch там, где нет ничего исключительного.

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

PS: goto запретили потому, что плохие программисты с его помощью пишут код хуже, чем без него.
Илья Бирман
Ага.
matiouchkine
А можно узнать, как планируется с помощью goto передать управление в чужой класс, исходный код которого недоступен?
Например, при написании плагина к чужому приложению — часто требуется отрапортовать об ошибке и отдать управление приложению?
Илья Бирман
Throw — это расширенный вариант goto, он может больше. Если вы помните, goto был признан плохим потому, что он ломает естественный порядок выполнения кода, из-за чего код часто становится нечитаемым. Однако goto работает только внутри некоторого логического блока, поэтому существенно испортить удобочитаемость кода он не может. Throw решает это проблему, так как позволяет прыгнуть в неопределённую точку пространства, как можно дальше от места, где мы его написали, чтобы никто никогда не понял, как это всё работает.

Так что, безусловно, с помощью goto нельзя сделать всего того, что можно сделать с помощью throw.
Scuro
Нет, ну try/catch это совсем другой механизм. Может в PHP уже пофигу, но языках более низкого уровня он требует совсем других накладных расходов, что бывает важно. Если кто-то использует try/catch именно как замену goto, то он, прямо скажем, не очень умный человек.
Ваня Солнцев
Какой-то дурак сказал, что goto это зло, а все и давай повторять. На самом деле полно исходников на С и С++, в которых goto используется в КАЖДОЙ функции.
Обычный оператор, каких много. А идиотам на слово не надо верить :)
Андрей Майоров
На самом-то деле, для заменты goto придумали совсем другую конструкцию:


while( true ) { // Label1:
  // do something
  // ...
  if( condition )
     continue; // Goto Label1:
  else
     break;
}


WBR,
XOR
Андрей Майоров
Да, wiki-posting мою конструкцию очень сильно подкосил. :(
Илья Бирман
Я подправил
blib
а как же finally ?
Илья Бирман
Whatever...
Zoreslav Khimich
Выясни, для начало, что такое try/catch, а уж потом говори глупости.
Ваня Солнцев
Выясни, для начало, что такое try/catch, а уж потом говори глупости
Хм, хоть стой хоть падай...
Самое распространенное применение goto в С:

{
  int *i = NULL;
  do_something();
  if(error) goto err;
  do_something2();
  i = new i;
  do_something3();
  if(another_error) goto err;
  do_something4();
err:
if(i)
  free(i);
}


Это — аналог try-catch-finally.
A!e%
Да... Народ, а читать/учиться будем?

1. Злой дядька, который сказал, что goto — плохо, кажися Дейкстра. У него много прав и в том числе говорить такое.
2. Goto в одном (!) случае (выход из многоуровнего цикла) и сейчас признается разумным.
3. Вполне доказано, что можно обойтись без goto __всегда__. При этом также говорится, что goto __усложняет__ восприятие текста программы. Поскольку непонятно, куда идет переход и потом очень сложно этот переход туды-сюды отслеживать. В данном аксепте написание плохого кода равносильно использованию goto.

И вообще, причем тут try-catch? Бред какой-то. :-) (без оскорблений, просто мысль такая)

Ну, а то, что Ваня Солнцев накосячил — это совсем да :-)
Илья Бирман
Самый большой бред — это твой пункт 3. Почему все так любят говорить, что «доказано, что можно обойтись без goto»?

Ну и что?

Доказано, что можно обойтись без: if, else, while, repeat, for, foreach, try, throw, catch, finally, class, abstract, final, private, public, string... Этот список можно продолжать бесконечно. Из этого никак не следует, что нужно отказаться от всего этого.
М-си
Эх. Пошаговая процедура:
1 Можно обойтись без goto в подавляющем количестве случаев без значимого количества накладных расходов. Это то, что говорится в п.3 выше как «доказано».
1 Использование goto ухудшает восприятие кода — значимо увеличивает накладные расходы. Это то, что говорится в п.3 выше как «доказано».
1 Из вышеизложенного следует, что использование оператора goto в подавляющем количестве случаев ведёт к накладным расходам (здесь, расходам, не связанным с решением основной задачи).
1 Случаи-исключения (такие, как «многоуровневый цикл») — не попадают под эту процедуру. Это то, что говорится в п. 2 выше.
1 Если вашей задачей является оптимизация расходов, то вам лучше избегать оператора goto.
1 Размышления, подобные этой процедуре, являются накладными расходами.
1 Если вашей задачей является оптимизация расходов, то вам лучше избегать этих размышлений.
1 Для избежания размышлений можно пользоваться «правилом» или «табу» на оператор goto. Их ещё называют «шаблонами использования операторов», «шаблонами кода» и подобной чушью.

Если, конечно, Вам действительно была непонятна логика пп.2,3 выше — надеюсь, что это упрощённое разъяснение Вам поможет.
Удачи!
Илья Бирман
Да понятно это всё. Я ж не о том говорю. А да ну нафиг.
М-си
Если коротко, то ГОСТ придумали очень и очень глупые люди, выходит.
Илья Бирман
Нет же...

Эх. Придётся писать ещё одну заметку на тему «Чем ГОСТ отличается от табу на goto».
Популярное
Эти ссылки принесут мне миллионы: Гадание, сонник