Подписаться на блог
В Твиттере

Реплики и ссылки на заметки

В Фейсбуке

Ссылки на заметки

Вконтакте

Ссылки на заметки

В Телеграме

Ссылки на заметки

В Тумблере

Заметки целиком

В Же-же

Заметки целиком

По РСС

Заметки целиком

Если что-то из этого не работает, напишите мне: ilyabirman@ilyabirman.ru.

Goto vs. Throw

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

Самое интересное, что когда люди поняли, что goto всё-таки нужен, но уже было слишком распространено мнение, что «им пользуются только лохи», они придумали throw. Причём, замаскировали его так, чтобы сразу трудно было догадаться, что это просто goto переименовали:
  • Сделали синтаксис try/catch (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».

Пользовательский интерфейс
Доступен первый раздел
электронного учебника

Популярное
Эти ссылки принесут мне миллионы: Гадание, сонник