Каковы допустимые варианты использования goto?

Возможный дубликат:
Примеры хороших gotos на C или C ++

Какие варианты использования оператора goto вы считаете приемлемыми? Я обсуждаю некоторые рекомендации по кодированию для встроенной работы C и задаюсь вопросом, есть ли случаи, когда goto - самый чистый способ делать что-то.


person Community    schedule 03.06.2010    source источник
comment
интересным чтением по этой теме является Структурированное программирование с переходом к утверждениям, Д. Кнут. Он был написан в 1974 году, но до сих пор содержит интересные примеры и мысли.   -  person tonio    schedule 03.06.2010


Ответы (3)


Для C я считаю полезным использовать goto для общей точки выхода в некоторых функциях. Если вам нужно освободить ресурсы перед возвратом, неплохо сделать retval = -ERROR; goto fn_exit; вместо того, чтобы пытаться вырваться из нескольких уровней циклов for / while.

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

Вот недавний вопрос SO по использовании goto для управления ошибками. Я уверен, что просмотр тега goto даст вам еще больше ответов.

person Community    schedule 03.06.2010

Я обнаружил, что есть несколько мест, где goto может упростить логику. Мое правило состоит в том, что никакие 2 goto не перекрывают друг друга и что goto и его метка являются «близкими»; обычно не более 30 строк.

Обычно, когда у меня сложное условие, в котором мне нужно многое проверить, может помочь goto:

if ( condition1 && cond2 )
  if ( checkFile( file ) )
    goto DONE;
else
  if ( condition3 )
    goto DONE;

handleError();
return 0;

DONE:
...do something...
return 1;
person Community    schedule 03.06.2010
comment
Я могу придумать более элегантные решения без goto, так что это не сильный аргумент. Например, создание функции int done() и замена goto DONE на return done(). Почти всегда есть лучший способ, чем прибегать к goto. - person Clifford; 03.06.2010
comment
@Clifford, вы правы, мой пример выше очень упрощен; но в этом суть: я предлагаю использовать goto для сложной логики, которую нелегко продемонстрировать на простом примере. Теперь, в некоторых сложных задачах, я обнаружил, что простой goto является более прямым и ясным в отношении того, какое намерение лучше, чем другие решения. - person Gianni; 03.06.2010
comment
@Clifford вы предлагаете несколько операторов возврата внутри данной функции? - person simon; 04.06.2010
comment
@simon: Нет, я просто адаптировал структуру Джанни в наиболее очевидное решение без goto. Множественные возвраты - это отдельный аргумент, и я принимаю лишь незначительно лучшее. Поле для комментариев не поддается описанию лучшего решения, но, поскольку пример надуманный, я решил проигнорировать этот момент. - person Clifford; 04.06.2010
comment
@Gianni: Возможно, вы слишком усложнили свой пример, чтобы придумать пример, но если это пример сложной логики, которая приводит к приемлемому использованию goto, я бы посоветовал в первую очередь уменьшить сложность . Я бы назвал это «запутанным», а не «сложным» - person Clifford; 04.06.2010
comment
@Clifford: Мне действительно нравится часть моего собственного кода, в котором я использую goto. Затем попытался свести это к содержательному примеру. Сложная логика - это факт жизни, наша задача - справиться с этой сложностью, и я считаю, что иногда goto является хорошим инструментом для этой работы. Тот факт, что goto можно использовать для создания наихудшего кода, не означает, что любое использование будет плохим. - person Gianni; 04.06.2010
comment
Часто эта идиома полезна для освобождения динамически выделяемых ресурсов в конце функции с множеством возможных ранних точек выхода (состояния ошибок при системных вызовах и т. Д.) - person PBJ; 06.03.2011

Мое личное мнение заключается в том, что в современном языке программирования НЕТ приемлемого использования оператора goto.

«Заявление GOTO, признанное вредным», написанное покойным Эдсгером В. Дейкстрой, хорошо освещает эту проблему. Эту статью должен прочитать каждый разработчик программного обеспечения на планете.

Стоит отметить, что в цыганском языке из группы Дона Гуда в UT в Остине в конце 1970-х годов не было goto.

Стоит отметить, что Ichbiah и др. Включили goto в Ada только потому, что DoD явно потребовал этого в спецификации требований. Я помню, как читал, что Ичбия и его команда намеренно сделали синтаксис целевой метки goto настолько уродливым, насколько могли, чтобы метки торчали, как больные пальцы, и препятствовали использованию goto.

person Community    schedule 03.06.2010
comment
Мое личное мнение таково, что отношение к хорошей практике как к железным правилам демонстрирует либо недостаток гибкости, либо недостаток веры в свою способность принимать разумные решения. Иногда необходимо для политики компании, но не для личной политики. Лучшая языковая функция для использования - это та, которая наиболее простым и очевидным образом описывает намерение и логику. Это почти никогда GOTO. Не путайте "почти никогда" с "никогда". - person snarf; 12.12.2020
comment
@snarf, проблема состоит из двух частей. Первый - это влияние на программиста и программы, которые он пишет. Дейкстра и другие подробно остановились на этом. Второй - это влияние на компилятор, которому не уделяется столько внимания. КРАТКО, включение оператора goto в язык заставляет компилятор бороться с нанесенным им ущербом. Операторы Goto значительно усложняют определенные оптимизации: компилятор должен предполагать, что содержимое регистров значительно менее предсказуемо. - person John R. Strohm; 13.12.2020
comment
re: влияние на программиста, программисту рекомендуется крайне редко и разумно использовать GOTO. Я уже сказал об этом - используйте его, когда он делает код наиболее простым и удобным в сопровождении, т.е. почти никогда. Re: повреждение компилятора, что-то преждевременная оптимизация. GOTO не оптимизация, и, как и в других случаях, если вы когда-нибудь попытаетесь использовать ее как таковую, вам, безусловно, лучше использовать профилировщик. - person snarf; 13.12.2020
comment
Позвольте мне сказать это так. За почти пятьдесят лет, которые я занимаюсь этим, работая почти исключительно со встроенными системами, критически важными для обеспечения безопасности, я НИКОГДА не видел случая, чтобы GOTO делал код максимально простым и удобным в сопровождении. Насчет чего-то преждевременной оптимизации, вы ошибаетесь. Урс Амманн затронул этот конкретный момент в одной из своих статей о ранних компиляторах PASCAL, которые он написал в ETH-Zurich. - person John R. Strohm; 14.12.2020
comment
Если вы имеете дело с программным обеспечением, критичным для безопасности (десять секунд или пятьдесят лет, не имеет значения), надеюсь, вы работаете с более строгими стандартами кодирования. В любом случае, если вы уже решили, что это всегда неправильно, это никогда не будет казаться правильным. Так что мы просто ходим по кругу по этому поводу. Как я ошибаюсь насчет преждевременной оптимизации? Я думаю, ты неправильно понял то, что я сказал? Если только вы не выступаете за преждевременную оптимизацию. Или иметь какое-то отвращение к профилированию. Я призываю всех освободить свой разум. Используйте GOTO. Это ухудшает ваш код? Возьми его обратно! Только не бойтесь пробовать. - person snarf; 14.12.2020