Все знают о письмах Дейкстры редактору: переходите к утверждению, которое считается вредным (также здесь .html transcripts и здесь .pdf), и с того времени был огромный толчок, чтобы по возможности отказаться от оператора goto. Хотя можно использовать goto для создания неуправляемого, растягивающегося кода, он, тем не менее, остается в современных языках программирования . Даже усовершенствованная структура управления продолжением в Схеме может быть описана как сложный переход.
Какие обстоятельства оправдывают использование goto? Когда лучше избегать?
В качестве дополнительного вопроса: C предоставляет пару функций setjmp и longjmp, которые обеспечивают возможность перехода не только в текущем кадре стека, но и в любом из вызывающих кадров. Должны ли они считаться такими же опасными, как goto? Более опасно?
Сам Дейкстра пожалел о том звании, за которое не нес ответственности. В конце EWD1308 (также здесь .pdf) он написал:
Наконец короткая история для записи. В 1968 году в сообщениях АСМ был опубликован мой текст под заголовком « Заявление Гото считалось вредным », на который в последующие годы чаще всего будут ссылаться, к сожалению, однако, часто авторы, которые видели его не больше, чем его title, который стал краеугольным камнем моей славы, став шаблоном: мы увидели бы все виды статей под заголовком «X считается вредным» практически для любого X, включая статью под названием «Дейкстра считается вредным». Но что случилось? Я представил документ под заголовком « Дело против заявления Гото»", который, чтобы ускорить его публикацию, редактор превратился в" письмо в редакцию ", и в процессе он дал ему новое название своего собственного изобретения! Редактором был Никлаус Вирт.
Хорошо продуманная классическая статья на эту тему, которую можно сравнить с темой Дейкстры, - « Структурное программирование с переходом к утверждениям» , написанная Дональдом Кнутом. Чтение обоих помогает восстановить контекст и недогматическое понимание предмета. В этой статье сообщается мнение Дейкстры по этому делу, и оно еще более убедительно:
Дональд Э. Кнут: Я полагаю, что, представляя такую точку зрения, я на самом деле не сильно не согласен с идеями Дейкстры, поскольку он недавно написал следующее: «Пожалуйста, не попадитесь в ловушку веры в то, что я ужасно догматичен перейти к утверждению]. У меня неприятное ощущение, что другие делают из этого религию, как будто концептуальные проблемы программирования могут быть решены одним трюком, простой формой дисциплины кодирования! "
источник
goto
.goto
: совместное использование инструментов структурированного программирования для реализацииgoto
.Ответы:
Следующие утверждения являются обобщениями; Хотя всегда можно заявить об исключении, обычно (по моему опыту и скромному мнению) риски не стоят.
Сноски к вышесказанному:
Что касается пункта 2, рассмотрим следующий код:
В точке «сделать что-то» в коде мы можем с высокой степенью достоверности заявить, что
a
больше, чемb
. (Да, я игнорирую возможность незаполненного целочисленного переполнения. Давайте не будем искать простой пример.)С другой стороны, если код читался так:
Множество способов добраться до метки 10 означает, что нам нужно работать гораздо усерднее, чтобы быть уверенными в отношениях между
a
иb
на этом этапе. (На самом деле, в общем случае это неразрешимо!)Что касается пункта 4, само понятие «идти куда-то» в коде - всего лишь метафора. Ничто на самом деле не «движется» нигде внутри процессора, кроме электронов и фотонов (для ненужного тепла). Иногда мы отказываемся от метафоры для другой, более полезной. Я помню, что встречал (несколько десятилетий назад!) Язык, на котором
был реализован на виртуальной машине путем компиляции action-1 и action-2 как внеплановых подпрограмм без параметров, а затем с использованием одного кода операции VM с двумя аргументами, который использовал логическое значение условия для вызова одного или другого. Концепция была просто «выбрать, что вызвать сейчас», а не «иди сюда или иди туда». Опять просто смена метафоры.
источник
true
иfalse
бывают разных типов), и каждая ветвь if / else является в основном лямбда-выражением.goto
на современном языке программирования (Go) stackoverflow.com/a/11065563/3309046 .Мой коллега сказал, что единственная причина использовать GOTO - это если вы запрограммировали себя так далеко, что это единственный выход. Другими словами, правильный дизайн заблаговременно, и вам не нужно будет использовать GOTO позже.
Я подумал, что этот комикс прекрасно иллюстрирует: «Я мог бы реструктурировать поток программы или использовать вместо этого один маленький« GOTO »». GOTO - слабый выход, когда у вас слабый дизайн. Велоцирапторы охотятся на слабых .
источник
Иногда допустимо использовать GOTO в качестве альтернативы обработке исключений внутри одной функции:
Код COM, кажется, попадает в этот шаблон довольно часто.
источник
Я могу вспомнить только один раз, используя goto. У меня была серия из пяти вложенных подсчитанных циклов, и мне нужно было иметь возможность вырваться из всей структуры изнутри на основе определенных условий:
Я мог бы просто объявить булеву переменную break и использовать ее как часть условия для каждого цикла, но в этом случае я решил, что GOTO так же практичен и удобен для чтения.
Никакие велоцирапторы не напали на меня.
источник
goto
и дало нам структурированное программирование, также отказалось от ранней отдачи по той же причине. Все сводится к тому, насколько читаем код, насколько четко он выражает намерение программиста. Создание функции только для того, чтобы избежать использования некорректного ключевого слова, приводит к плохой сплоченности: лекарство хуже болезни.goto
, можно явно указать цель. С помощьюbreak 5;
(1) мне нужно сосчитать замыкания цикла, чтобы найти пункт назначения; и (2) если структура цикла когда-либо изменяется, вполне может потребоваться изменить это число, чтобы сохранить правильность назначения. Если я собираюсь избегатьgoto
, то выигрыш должен заключаться в том, что нет необходимости вручную отслеживать подобные вещи.У нас уже было это обсуждение, и я поддерживаю свою точку зрения .
Кроме того, я сыт по горло людьми, которые описывают языковые структуры более высокого уровня как «
goto
замаскированные», потому что они явно не понимают суть вообще . Например:Это полная чушь. Любая структура управления может быть реализована с точки зрения,
goto
но это наблюдение совершенно тривиально и бесполезно.goto
не считается вредным из-за его положительных эффектов, но из-за его отрицательных последствий, которые были устранены структурным программированием.Точно так же высказывание «GOTO - это инструмент, и, как и все инструменты, им можно пользоваться и злоупотреблять», совершенно не соответствует действительности. Ни один современный строитель не будет использовать камень и утверждать, что он «инструмент». Скалы были заменены молотками.
goto
был заменен контрольными структурами. Если бы строитель оказался в дикой природе без молотка, он, конечно, вместо этого использовал бы камень. Если программист должен использовать более низкий язык программирования, который не имеет функции X, ну, конечно, она может использоватьgoto
вместо этого. Но если она использует его где-то еще вместо соответствующей языковой функции, она явно не поняла язык должным образом и использует его неправильно. Это действительно так просто.источник
goto
. Вы правы, поскольку я не предлагаю аргумент противgoto
per se - я не собирался - поэтому нет никаких вопросов.Goto очень низок в моем списке вещей, чтобы включить в программу только ради этого. Это не значит, что это недопустимо.
Goto может быть хорош для конечных автоматов. Оператор switch в цикле (в порядке типичной важности): (а) фактически не является представителем потока управления, (б) некрасиво, (в) потенциально неэффективен в зависимости от языка и компилятора. Таким образом, вы заканчиваете тем, что пишете одну функцию на состояние и выполняете такие действия, как «return NEXT_STATE;» который даже похож на гото.
Конечно, сложно кодировать конечные автоматы так, чтобы их было легко понять. Однако ни одна из этих трудностей не связана с использованием goto, и ни одна из них не может быть уменьшена с помощью альтернативных структур управления. Если у вашего языка нет конструкции «конечного автомата». Мой нет.
В тех редких случаях, когда ваш алгоритм действительно наиболее понятен с точки зрения пути через последовательность узлов (состояний), связанных ограниченным набором допустимых переходов (gotos), а не каким-либо более конкретным потоком управления (циклы, условные выражения и т.д.) ), то это должно быть явным в коде. И вам следует нарисовать симпатичную диаграмму.
setjmp / longjmp может быть полезен для реализации исключений или поведения, подобного исключению. Несмотря на то, что они не одобряются повсеместно, исключения обычно считаются «действительной» структурой контроля
setjmp / longjmp «более опасны», чем goto, в том смысле, что их сложнее правильно использовать, не говоря уже о понятном.
Вывод goto из C не облегчит написание хорошего кода на C. На самом деле, он скорее упустит тот момент, что C должен выступать в качестве прославленного языка ассемблера.
Далее это будут «указатели, считающиеся вредными», затем «печать утки, считающаяся вредной». Тогда кто будет защищать вас, когда они заберут вашу небезопасную программную конструкцию? А?
источник
В Linux: Использование goto В Kernel Code на Kernel Trap обсуждается с Линусом Торвальдсом и «новым парнем» использование GOTO в коде Linux. Там есть несколько очень хороших моментов, и Линус одет в это обычное высокомерие :)
Некоторые отрывки:
-
-
источник
goto cleanup_and_exit
является одним из немногих «хороших» использования Гото осталось теперь у нас естьfor
,while
иif
управлять нашим потоком управления. Смотрите также: programmers.stackexchange.com/a/154980В C
goto
работает только в рамках текущей функции, которая стремится локализовать любые потенциальные ошибки.setjmp
иlongjmp
гораздо более опасны, будучи нелокальными, сложными и зависящими от реализации. Однако на практике они слишком неясны и необычны, чтобы вызывать много проблем.Я считаю, что опасность
goto
в С сильно преувеличена. Помните, что оригинальныеgoto
аргументы имели место еще во времена таких языков, как старомодный бейсик, где начинающие писали код для спагетти, например так:Здесь Линус описывает подходящее использование
goto
: http://www.kernel.org/doc/Documentation/CodingStyle (глава 7).источник
setjmp
/longjmp
было указано только тогда, когда они использовались в качестве средства перехода к точке в пределах области действия из других мест в той же области действия. Как только элемент управления выходит из области действия, в которойsetjmp
он выполняется, любая попытка использованияlongjmp
созданной структурыsetjmp
приведет к неопределенному поведению.GOTO A * 40 + B * 200 + 30
. Нетрудно понять, как это было очень удобно и очень опасно.Сегодня трудно понять грандиозное
GOTO
утверждение об этом утверждении, потому что люди, занимающиеся «структурированным программированием», в основном выиграли дебаты, а современные языки имеют достаточную структуру потоков управления, чтобы их избежатьGOTO
.Посчитайте количество
goto
s в современной программе на Си. Теперь добавьте числоbreak
,continue
иreturn
заявлений. Кроме того, добавьте несколько раз вы используетеif
,else
,while
,switch
илиcase
. Это примерно столько, сколько уGOTO
вашей программы было бы, если бы вы писали на Фортране или Бейсике в 1968 году, когда Дейкстра написал свое письмо.Языки программирования в то время испытывали недостаток в потоке управления. Например, в оригинальном дартмутском бейсике:
IF
заявления не былоELSE
. Если вы хотели один, вы должны были написать:Даже если ваше
IF
утверждение не нужноELSE
, оно все равно будет ограничено одной строкой, которая обычно состоит изGOTO
.Там не было никакого
DO...LOOP
заявления. ДляFOR
нециклов, вы должны были закончить цикл с явнымGOTO
илиIF...GOTO
вернуться к началу.Не Существовал нет
SELECT CASE
. Вы должны были использоватьON...GOTO
.Таким образом, вы в конечном итоге с большим из
GOTO
с в вашей программе. И вы не могли зависеть от ограниченияGOTO
s в пределах одной подпрограммы (потому чтоGOSUB...RETURN
была такая слабая концепция подпрограмм), так что этиGOTO
s могли пойти куда угодно . Очевидно, что это затрудняло контроль потока управления.Вот откуда
GOTO
пришло анти- движение.источник
420 if (rare_condition) then 3000
//430 and onward: rest of loop and other main-line code
//3000 [code for rare condition]
//3230 goto 430
. Таким образом, написание кода позволяет избежать любых взятых ветвей или переходов в общем случае основной линии, но это усложняет задачу. Избегание ветвей в ассемблерном коде может быть хуже, если некоторые ветви ограничены, например, +/- 128 байтами и иногда не имеют дополнительных пар (например, существует «cjne», но не «cje»).cjne r0,expected_value,first_comp_springboard
/.../cjne r1,unexpected_value,second_comp_fallthrough
// `ajmp second_comp_target` //first_comp_springboard: ajmp first_comp_target
//second_comp_fallthrough: ...
. Не очень хороший паттерн кодирования, но когда учитываются отдельные циклы, каждый делает такие вещи. Конечно, в 1960-х такие уровни оптимизации были более важными, чем сегодня, тем более что современные процессоры часто требуют странных оптимизаций, а системы компиляции точно в срок могут применять оптимизирующий код для процессоров, которых не было, когда соответствующий код был написан.Go To может обеспечить своего рода замену для «реальной» обработки исключений в определенных случаях. Рассматривать:
Очевидно, этот код был упрощен, чтобы занимать меньше места, поэтому не зацикливайтесь на деталях. Но рассмотрим альтернативу, которую я видел слишком много раз в производственном коде, так как кодеры идут на абсурдную длину, чтобы избежать использования goto:
Теперь функционально этот код делает то же самое. На самом деле код, сгенерированный компилятором, практически идентичен. Тем не менее, в стремлении программиста умиротворить Ногото (страшного бога академического упрека) этот программист полностью нарушил основную идиому, которую
while
представляет цикл, и сделал реальное число для читабельности кода. Это не лучше.Итак, мораль этой истории в том, что если вы прибегаете к чему-то действительно глупому, чтобы избежать использования goto, то не делайте этого.
источник
break
утверждения находятся внутри контрольной структуры, четко показывает, что они делают. В этомgoto
примере человек, читающий код, должен просмотреть код, чтобы найти метку, которая теоретически могла бы быть перед структурой управления. Я не достаточно опытен в старом стиле C, чтобы судить, что одно определенно лучше другого, но в любом случае есть компромиссы.break
s находятся внутри цикла, ясно показывает, что они выходят из цикла . Это не «именно то, что они делают», так как на самом деле петли нет вообще! Ничто в этом не имеет шансов повториться, но до конца не ясно. Тот факт, что у вас есть «цикл», который никогда не запускается более одного раза, означает, что управляющие структуры злоупотребляют. Наgoto
примере программист может сказатьgoto error_handler;
. Это более явно, и даже менее трудно следовать. (Ctrl + F, "error_handler:", чтобы найти цель. Попробуйте сделать это с помощью "}".)Дональд Э. Кнут ответил на этот вопрос в книге «Грамотное программирование», 1992 CSLI. На стр. 17 есть эссе « Структурированное программирование с использованием операторов goto » (PDF). Я думаю, что статья могла быть опубликована и в других книгах.
В статье описывается предложение Дейкстры и описываются обстоятельства, при которых оно действительно. Но он также приводит ряд контрпримеров (проблем и алгоритмов), которые нельзя легко воспроизвести, используя только структурированные циклы.
Статья содержит полное описание проблемы, историю, примеры и контрпримеры.
источник
Гото считается полезным.
Я начал программировать в 1975 году. Для программистов эпохи 1970-х годов слова «Goto считать вредными» говорили более или менее о том, что новые языки программирования с современными структурами управления стоит попробовать. Мы попробовали новые языки. Мы быстро обратились. Мы никогда не возвращались.
Мы никогда не возвращались, но, если вы моложе, то вы никогда не были там в первую очередь.
Теперь фон в древних языках программирования может быть не очень полезным, кроме как как показатель возраста программиста. Несмотря на это, молодые программисты не имеют такого опыта, поэтому они больше не понимают сообщения, которое лозунг «goto признан вредным» передал целевой аудитории во время его представления.
Лозунги, которые никто не понимает, не очень освещают. Вероятно, лучше всего забыть такие лозунги. Такие лозунги не помогают.
Однако этот конкретный лозунг «Гото считается вредным» обрел собственную жизнь нежити.
Может ли Гото не быть оскорбленным? Ответ: конечно, но что с того? Практически каждый элемент программирования может быть нарушен.
bool
Например, скромным злоупотребляют чаще, чем некоторые из нас хотели бы верить.В отличие от этого, я не могу вспомнить ни одного фактического случая злоупотребления гото с 1990 года.
Самая большая проблема с goto, вероятно, не техническая, а социальная. Иногда кажется, что программисты, которые не знают очень много, считают, что осуждающее goto заставляет их звучать умно. Возможно, вам придется время от времени удовлетворять таких программистов. Такова жизнь.
Самое плохое в goto сегодня - это то, что он недостаточно используется.
источник
Привлеченный Джеем Баллоу, добавившим ответ, я добавлю свои £ 0,02. Если бы Бруно Раншарт еще не сделал этого, я бы упомянул статью Кнута «Структурированное программирование с утверждениями GOTO».
Одна вещь, которую я не видел, обсуждалась, это своего рода код, который, хотя и не совсем распространенный, преподавался в учебниках Фортрана. Такие вещи, как расширенный диапазон цикла DO и подпрограммы с открытым кодом (помните, это будет Fortran II, или Fortran IV, или Fortran 66, а не Fortran 77 или 90). По крайней мере, есть вероятность, что синтаксические детали неточны, но концепции должны быть достаточно точными. Фрагменты в каждом случае находятся внутри одной функции.
Обратите внимание, что в превосходной, но устаревшей (и не изданной) книге Kernighan & Plauger «Элементы стиля программирования, 2-й Эдн » содержатся некоторые реальные примеры злоупотребления GOTO из учебников по программированию его эпохи (конец 70-х годов). Однако материал ниже не из этой книги.
Расширенный диапазон для петли DO
Одной из причин такой ерунды была старая старомодная перфокарта. Вы можете заметить, что метки (красиво не по порядку, потому что это был канонический стиль!) Находятся в столбце 1 (фактически, они должны были быть в столбцах 1-5), а код - в столбцах 7-72 (столбец 6 был продолжением колонка маркера). Столбцам 73-80 будет присвоен порядковый номер, и существуют машины, которые сортируют колоды перфокарт в порядке порядкового номера. Если ваша программа была на последовательных карточках и вам нужно было добавить несколько карточек (строк) в середину цикла, вам нужно было бы перевыпускать все после этих дополнительных строк. Однако, если вы заменили одну карту на GOTO, вы можете избежать повторного упорядочения всех карт - вы просто подсовываете новые карты в конце процедуры с новыми порядковыми номерами. Считайте, что это первая попытка «зеленых вычислений»
О, вы также можете заметить, что я обманываю, а не кричу - Фортран IV был написан в верхнем регистре как обычно.
Открытая подпрограмма
GOTO между метками 76 и 54 является версией вычисленного goto. Если переменная i имеет значение 1, перейдите к первой метке в списке (123); если оно имеет значение 2, перейдите ко второму и так далее. Фрагмент от 76 до вычисленного goto является подпрограммой с открытым кодом. Это был кусок кода, выполняемый скорее как подпрограмма, но записанный в теле функции. (У Fortran также были операторные функции - встроенные функции, которые помещались в одну строку.)
Существовали худшие конструкции, чем вычисленное goto - вы могли назначать метки переменным, а затем использовать назначенное goto. Googling назначил goto, чтобы сообщить мне, что он был удален из Фортрана 95. Примите участие в революции структурного программирования, о которой можно было бы сказать, что она началась публично, с письмом или статьей Дейкстры «GOTO считают вредным».
Без некоторого знания того, что было сделано в Фортране (и на других языках, большинство из которых по праву попали на обочину), нам, новичкам, трудно понять масштаб проблемы, с которой сталкивался Дейкстра. Черт, я начал программировать только через десять лет после того, как это письмо было опубликовано (но у меня действительно было несчастье программировать на Фортране IV некоторое время)
источник
goto
«в дикой природе», вопрос « Требуется: рабочий алгоритм сортировки Бозе-Хиббарда» показывает некоторый (Algol 60) код, опубликованный в 1963 году. Исходный макет не сравнивается с современными стандартами кодирования. Уточненный (с отступом) код все еще довольно непостижим. Вgoto
ведомости там делают сделать (очень) трудно понять , что алгоритм является.Там нет таких вещей, как GOTO считается вредным .
GOTO - это инструмент, и, как и все инструменты, им можно пользоваться и злоупотреблять .
Однако в мире программирования существует множество инструментов, которые имеют тенденцию злоупотреблять чаще, чем использоваться , и GOTO является одним из них. С констатацией Delphi это совсем другая.
Лично я не использую ни один в типичном коде , но у меня было странное использование как GOTO, так и WITH, которые были оправданы, и альтернативное решение содержало бы больше кода.
Лучшим решением для компилятора было бы просто предупредить вас о том, что ключевое слово испорчено , и вам нужно будет добавить пару прагматических директив вокруг оператора, чтобы избавиться от предупреждений.
Это все равно что говорить своим детям не бегать с ножницами . Ножницы неплохие, но их использование, возможно, не лучший способ сохранить здоровье.
источник
goto
ключевое слово было удалено из C #, концепция «перейти сюда» все еще существует в IL. Бесконечный цикл можно легко построить без ключевого слова goto. Если это отсутствие гарантии того, что вызываемый код вернется, по вашему мнению, означает «неспособность рассуждать о коде», то я бы сказал, что у нас никогда не было такой возможности.goto
C # не является настоящим "goto" в первоначальном смысле этого слова. Это гораздо более слабая версия, которая позволяет прыгать только внутри функции. Смысл, в котором я использую «goto», позволяет прыгать в любом месте процесса. Таким образом, хотя C # имеет ключевое слово "goto", оно, возможно, никогда не имело, настоящего goto. Да, настоящее goto доступно на уровне IL, так же, как и при компиляции любого языка до сборки. Но программист защищен от этого, не может использовать его в нормальных условиях, поэтому он не считается.Такого никогда не было, если вы могли думать сами.
источник
Поскольку я начал делать некоторые вещи в ядре Linux, gotos не беспокоит меня так сильно, как раньше. Сначала я был в ужасе от того, что они (ребята из ядра) добавили gotos в мой код. С тех пор я привык к использованию gotos, в некоторых ограниченных контекстах, и теперь буду иногда использовать их сам. Как правило, это переход, который переходит к концу функции, чтобы выполнить какую-то очистку и выручить, а не дублировать ту же самую очистку и выкуп в нескольких местах в функции. И, как правило, это не что-то достаточно большое, чтобы передать другой функции - например, освобождение некоторых локально (k) malloc-переменных является типичным случаем.
Я написал код, который использовал setjmp / longjmp только один раз. Это было в программе MIDI барабанного секвенсора. Воспроизведение происходило в отдельном процессе от всего взаимодействия с пользователем, и процесс воспроизведения использовал общую память с процессом пользовательского интерфейса, чтобы получить ограниченную информацию, необходимую для воспроизведения. Когда пользователь хотел остановить воспроизведение, процесс воспроизведения просто выполнял longjmp «назад в начало», чтобы начать сначала, а не какое-то сложное раскручивание того места, где оно выполнялось, когда пользователь хотел остановить его. Это работало отлично, было просто, и у меня никогда не было проблем или ошибок, связанных с этим в этом случае.
У setjmp / longjmp есть свое место - но это место, которое вы вряд ли посетите, но время от времени.
Изменить: я только что посмотрел на код. На самом деле я использовал siglongjmp (), а не longjmp (не то, чтобы это было важно, но я забыл, что siglongjmp вообще существует).
источник
Если вы пишете виртуальную машину на C, то получается, что использование (gcc) вычисленных gotos выглядит так:
работает намного быстрее, чем обычный переключатель внутри цикла.
источник
&&op_inc
конечно, не компилируется, потому что (слева)&
ожидает lvalue, но (справа)&
возвращает rvalue.Потому что
goto
может быть использовано для запутывания метапрограммированияGoto
является высокоуровневым и низкоуровневым управляющим выражением, и в результате у него просто нет подходящего шаблона проектирования, подходящего для большинства задач.Это низкоуровневый в том смысле , что Гото примитивная операция , которая реализует нечто более высокое , как
while
иforeach
или что - то.Это высокий уровень в том смысле, что при использовании определенными способами он принимает код, который выполняется в четкой последовательности, непрерывным образом, за исключением структурированных циклов, и он превращает его в фрагменты логики, которые при достаточном количестве
goto
s являются захватом -пакет логики динамически пересобирается.Таким образом, есть прозаическая и злая сторона
goto
.Прозаическая сторона является то , что направленная вверх Гото может реализовать вполне разумный цикл и направленный вниз Гото может сделать вполне разумным
break
илиreturn
. Конечно, фактическийwhile
,break
илиreturn
был бы намного более читабельным, так как бедному человеку не пришлось бы имитировать эффектgoto
, чтобы получить общую картину. Итак, плохая идея в целом.Сторона зла включает рутину , не используя Гота для некоторого времени, перерыв, или вернуться, но использовать его для того, что называется спагетти логики . В этом случае разработчик goto-happy строит кусочки кода из лабиринта goto, и единственный способ понять это - это симулировать его мысленно в целом, ужасно утомительная задача, когда есть много goto. Я имею в виду, представьте себе проблему оценки кода, где
else
точка не является точной инверсиейif
, где вложенныеif
s могут допускать некоторые вещи, которые были отвергнуты внешнимif
, и т. Д., И т. Д.Наконец, чтобы действительно охватить эту тему, мы должны отметить, что по существу все ранние языки, кроме Algol, первоначально делали только отдельные утверждения в соответствии с их версиями
if-then-else
. Таким образом, единственный способ сделать условный блок состоял в том, чтобыgoto
обойти его, используя обратный условный блок . Безумно, я знаю, но я прочитал некоторые старые спецификации. Помните, что первые компьютеры были запрограммированы в двоичном машинном коде, поэтому я предполагаю, что любой тип HLL был спасителем; Я предполагаю, что они не были слишком разборчивы в том, какие именно функции HLL они получили.Сказав все, что я использовал, вставлял одну
goto
в каждую программу, которую я написал «просто чтобы раздражать пуристов» .источник
Отказ в использовании оператора GOTO для программистов - это все равно, что сказать плотнику не использовать молоток, поскольку он может повредить стену, пока он забивает гвоздь. Настоящий программист знает, как и когда использовать GOTO. Я следовал за некоторыми из этих так называемых «структурированных программ». Я видел такой ужасный код, чтобы избежать использования GOTO, чтобы я мог застрелить программиста. Хорошо, в защиту другой стороны, я тоже видел настоящий спагетти-код, и эти программисты тоже должны быть застрелены.
Вот только один небольшой пример кода, который я нашел.
-----------------------ИЛИ----------------------
источник
goto
- и знает, почему . Избегать языковой конструкции-табу, потому что так сказал $ program_guru, это и есть определение программирования с использованием груза.«По этой ссылке http://kerneltrap.org/node/553/2131 »
По иронии судьбы, устранение goto привело к ошибке: вызов спин-блокировки был опущен.
источник
Первоначальный документ следует рассматривать как «Безусловный GOTO считается вредным». В частности, он защищал форму программирования, основанную на условных (
if
) и итеративных (while
) конструкциях, а не на тесте и прыжке, обычном для раннего кода.goto
все еще полезен в некоторых языках или обстоятельствах, где не существует соответствующей структуры контроля.источник
О единственном месте я согласен Goto может быть использовано, когда вам придется иметь дело с ошибками, и каждый конкретный момент происходит ошибка требует специальной обработки.
Например, если вы захватываете ресурсы и используете семафоры или мьютексы, вы должны захватывать их по порядку и всегда освобождать их противоположным образом.
Некоторый код требует очень странной схемы захвата этих ресурсов, и вы не можете просто написать легко поддерживаемую и понятную структуру управления, чтобы правильно обрабатывать как захват, так и освобождение этих ресурсов, чтобы избежать тупика.
Всегда возможно сделать это правильно без goto, но в этом и некоторых других случаях Goto на самом деле является лучшим решением, прежде всего для удобочитаемости и удобства обслуживания.
-Адам
источник
Одним из современных применений GOTO является компилятор C # для создания конечных автоматов для перечислителей, определяемых возвращаемым доходом.
GOTO - это то, что должно использоваться компиляторами, а не программистами.
источник
goto
. Там, где мы могли бы использоватьgoto
конечный автомат, закодированный вручную для реализации перечислителя, мы можем просто использоватьyield
вместо этого.Пока C и C ++ (среди других преступников) не помечают разрывы и продолжаются, goto будет продолжать играть свою роль.
источник
Если бы само GOTO было злом, компиляторы были бы злы, потому что они генерировали JMP. Если бы прыжок в блок кода, особенно после указателя, был изначально злым, инструкция RETurn была бы злой. Скорее зло находится в потенциальной возможности злоупотребления.
Иногда мне приходилось писать приложения, которые должны были отслеживать количество объектов, где каждый объект должен был следовать сложной последовательности состояний в ответ на события, но все это было определенно однопоточным. Типичная последовательность состояний, если она представлена в псевдокоде:
Я уверен, что это не ново, но способ, которым я обработал это в C (++), заключался в определении некоторых макросов:
Затем (предполагая, что состояние изначально равно 0), структурированный конечный автомат, приведенный выше, превращается в структурированный код:
В зависимости от этого, могут быть CALL и RETURN, поэтому некоторые конечные автоматы могут действовать как подпрограммы других конечных автоматов.
Это необычно? Да. Требуется ли некоторое обучение со стороны сопровождающего? Да. Это обучение окупается? Я думаю так. Можно ли это сделать без GOTO, которые прыгают в блоки? Нет.
источник
Я избегаю этого, потому что коллега / менеджер, несомненно, поставит под сомнение его использование либо в обзоре кода, либо когда они наткнуться на него. Хотя я думаю, что он использует (например, случай обработки ошибок) - вы столкнетесь с проблемой другого разработчика, у которого будут какие-то проблемы с ним.
Это того не стоит.
источник
На самом деле я вынужден был использовать goto, потому что буквально не мог придумать лучшего (более быстрого) способа написания этого кода:
У меня был сложный объект, и мне нужно было поработать над ним. Если объект находился в одном состоянии, я мог бы сделать быструю версию операции, в противном случае мне пришлось бы делать медленную версию операции. Дело в том, что в некоторых случаях, в середине медленной операции, можно было понять, что это можно было сделать с быстрой операцией.
Это был критический по скорости фрагмент кода пользовательского интерфейса в реальном времени, поэтому я искренне считаю, что GOTO здесь оправдан.
Хьюго
источник
Почти во всех ситуациях, когда можно использовать goto, вы можете сделать то же самое, используя другие конструкции. Goto все равно используется компилятором.
Я лично никогда не использую это явно, никогда не нужно.
источник
Одна вещь, которую я не видел ни в одном из ответов, заключается в том, что решение «goto» часто более эффективно, чем одно из часто упоминаемых решений для структурированного программирования.
Рассмотрим случай с множеством вложенных циклов, где использование goto вместо набора
if(breakVariable)
секций, очевидно, более эффективно. Решение «Поместите ваши циклы в функцию и используйте return» часто совершенно неоправданно. В вероятном случае, когда в циклах используются локальные переменные, теперь вам нужно передать их все через параметры функции, потенциально обрабатывая множество дополнительных головных болей, которые возникают из-за этого.Теперь рассмотрим случай очистки, который я сам использовал довольно часто и который настолько распространен, что предположительно отвечает за структуру try {} catch {}, недоступную во многих языках. Количество проверок и дополнительных переменных, которые требуются для выполнения одного и того же действия, намного хуже, чем одна или две инструкции для перехода, и опять же, решение дополнительной функции вовсе не является решением. Вы не можете сказать мне, что это более управляемо или более читабельно.
Теперь для многих программистов пространство кода, использование стека и время выполнения могут не иметь значения во многих ситуациях, но когда вы находитесь во встроенной среде, где для работы с кодом требуется всего 2 КБ, нужно добавить 50 байтов дополнительных инструкций, чтобы избежать однозначного определения «goto» просто смешно, и это не такая редкая ситуация, как считают многие программисты высокого уровня.
Утверждение, что «goto вредно», очень помогло в переходе к структурированному программированию, даже если оно всегда было чрезмерным обобщением. На данный момент, мы все слышали это достаточно, чтобы с осторожностью использовать его (как мы должны). Когда это, очевидно, правильный инструмент для работы, нам не нужно бояться этого.
источник
Вы можете использовать его для выхода из глубоко вложенного цикла, но большую часть времени ваш код может быть подвергнут рефакторингу, чтобы быть чище без глубоко вложенных циклов.
источник