Goto vs. Throw

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

Самое интересное, что когда люди поняли, что goto всё-таки нужен, но уже было слишком распространено мнение, что «им пользуются только лохи», они придумали throw. Причём, замаскировали его так, чтобы сразу трудно было догадаться, что это просто goto переименовали:

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

Если писать код лично для себя, то можно без проблем пользоваться goto, или try/catch вместо goto, и даже try/catch там, где нет ничего исключительного.

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

PS: goto запретили потому, что плохие программисты с его помощью пишут код хуже, чем без него.

Илья Бирман

Ага.

matiouchkine 2004

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

Илья Бирман

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

Так что, безусловно, с помощью goto нельзя сделать всего того, что можно сделать с помощью throw.

Scuro 2004

Нет, ну try/catch это совсем другой механизм. Может в PHP уже пофигу, но языках более низкого уровня он требует совсем других накладных расходов, что бывает важно. Если кто-то использует try/catch именно как замену goto, то он, прямо скажем, не очень умный человек.

Ваня Солнцев 2004

Какой-то дурак сказал, что goto это зло, а все и давай повторять. На самом деле полно исходников на С и С++, в которых goto используется в КАЖДОЙ функции.
Обычный оператор, каких много. А идиотам на слово не надо верить :)

Андрей Майоров 2004

На самом-то деле, для заменты goto придумали совсем другую конструкцию:

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

WBR,
XOR

Андрей Майоров 2004

Да, wiki-posting мою конструкцию очень сильно подкосил. :(

Илья Бирман

Я подправил

blib 2004

а как же finally ?

Илья Бирман

Whatever...

Zoreslav Khimich 2004

Выясни, для начало, что такое try/catch, а уж потом говори глупости.

Ваня Солнцев 2004

!!Выясни, для начало, что такое 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% 2004

Да... Народ, а читать/учиться будем?

  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... Этот список можно продолжать бесконечно. Из этого никак не следует, что нужно отказаться от всего этого.

М-си 2004

Эх. Пошаговая процедура:
1 Можно обойтись без goto в подавляющем количестве случаев без значимого количества накладных расходов. Это то, что говорится в п.3 выше как «доказано».
1 Использование goto ухудшает восприятие кода — значимо увеличивает накладные расходы. Это то, что говорится в п.3 выше как «доказано».
1 Из вышеизложенного следует, что использование оператора goto в подавляющем количестве случаев ведёт к накладным расходам (здесь, расходам, не связанным с решением основной задачи).
1 Случаи-исключения (такие, как «многоуровневый цикл») — не попадают под эту процедуру. Это то, что говорится в п. 2 выше.
1 Если вашей задачей является оптимизация расходов, то вам лучше избегать оператора goto.
1 Размышления, подобные этой процедуре, являются накладными расходами.
1 Если вашей задачей является оптимизация расходов, то вам лучше избегать этих размышлений.
1 Для избежания размышлений можно пользоваться «правилом» или «табу» на оператор goto. Их ещё называют «шаблонами использования операторов», «шаблонами кода» и подобной чушью.

Если, конечно, Вам действительно была непонятна логика пп.2,3 выше — надеюсь, что это упрощённое разъяснение Вам поможет.
Удачи!

Илья Бирман

Да понятно это всё. Я ж не о том говорю. А да ну нафиг.

М-си 2004

Если коротко, то ГОСТ придумали очень и очень глупые люди, выходит.

Илья Бирман

Нет же...

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

Мои книги