2013-09-24 3 views
2

Заявление goto является табу в моей работе.
Таким образом, возникает следующий вопрос ...Есть ли ситуация в delphi, где GOTO - единственное решение?

Возможна ли ситуация, когда goto является допустимым решением?

+3

В течение почти 20 лет Delphi и, возможно, нескольких миллионов строк я никогда не использовал инструкцию goto ... – Despatcher

+3

В Delphi-XE4 есть 14 'goto' операторов в исходной директории. –

+0

@LURD Они в основном выглядят оправданными, кроме двух в MXDSSQRY –

ответ

5

Первоначально GOTO был добавлен в Pascal для обработки ошибок, в том числе взаимосвязанных процессуальных форм, Борланд (/ Embarcadero) не реализованы (например: GOTOing от внутренней процедуры родителя), просто (*)

Таким образом, GOTO можно считать предшественником исключений.

По-прежнему существует практическое применение: в последний раз, когда я проверял, выпрыгивая из вложенного оператора IF с goto, все еще было быстрее в Delphi, а затем, если естественно, вывести код из вложенного. Оптимизации, подобные этим, иногда используют, например, код сжатия и другой сложный код обработки дерева с глубоко вложенными циклами или условными операторами.

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

Этот элемент можно рассматривать как часть простого Pascal уровня Object Pascal, так же как C++ по-прежнему позволяет использовать C почти полностью.

(конечно, так как оптимизированный код сжатия в Delphi доставляется только в .o форме, то трудно найти примеры в коде Delphi. Код JPEG имеет некоторые, но это C перевод)

(*) Оригинальный паскаль, а IIRC даже Turbo Pascal не позволяет досрочно выйти из процедуры с EXIT. То же самое для CONTINUE и BREAK.

+0

TP7 имеет ПРОДОЛЖЕНИЕ, ПЕРЕРЫВ и ВЫХОД. Первые два были введены в TP7, а выход был раньше. –

+0

'Exit' был в TP3. –

6

Возможна ли ситуация, когда a GOTO является единственным допустимым решением?

Я полагаю, это зависит от того, что вы подразумеваете под действительным. Я полагаю, вы спрашиваете, существует ли программа, которая может быть написана только с использованием инструкции goto. В этом случае ответ заключается в том, что такой программы нет. Delphi является Turing в комплекте с или без заявления goto.

Однако, если мы готовы расширить обсуждение, включив другие языки, бывают ситуации, когда goto - хорошее решение, даже лучшее решение. Сценарий, который чаще всего приходит на ум, заключается в реализации процедур ввода-вывода и обработки ошибок на языках без структурированной обработки исключений. Если вы изучите исходный код Linux, вы обнаружите, что широко используется goto. Я ожидаю, что то же самое относится к исходному коду Windows.

3

Goto очень старый. Это предшествует подпрограмм, таких как функции и процедуры! Это также очень опасно и может сделать ваш код менее удобочитаемым (для других или для вас несколько месяцев спустя).

В теории не может быть ситуации, когда goto требуется. Я не буду повторять теорию о ленточных машинах Тьюринга здесь, но используя выбор и итерацию, вы можете переупорядочить код так, чтобы во всех возможных входных значениях появился тот же результат.

На практике, хотя, иногда «под рукой» и «лучше читаемым» на «отскочить» от потока кода в определенных условиях, и там исключения бывают. raise отрывается от текущего исполнения, и прыжок до ближайшего finally или except раздел. Это безопаснее, потому что они работают каскадом и обеспечивают лучший способ обработки контекста в случае одного из этих пограничных условий. (И есть также break и abort и exit)

+1

Да, но настоящим жалом было заявление 'ALTER' в COBOL, которое могло бы динамически изменять (действительно) цели оператора GOTO.Поэтому вы даже не могли поверить, что говорится в заявлении 'GOTO' ... –

+0

@marjan К сожалению, из COBOL это заявление COMEFROM. –

+0

Не в Паскаль. Он был добавлен в Pascal специально для обработки ошибок, –

3

Что-то вроде 15 лет назад Я использовал инструкцию goto в Delphi для преобразования one of Bob Jenkins's hash functions с C на Pascal. Функция C имеет инструкцию switch() без разрывов после каждого случая, и вы не можете сделать это с помощью оператора case Pascal. Поэтому я превратил его в кучу ярлыков Pascal и gotos. Думаю, вам все равно придется делать то же самое с новейшими версиями Delphi. Редактировать: Я думаю, использование gotos все равно было бы разумным способом сделать это. Получает выполненную работу, легко понять, ограниченную коротким блоком кода, а не опасно.

+2

Оператор switch C-style с случаями без прерывания может быть преобразован в ряд операторов if, с 'x и not (y)' для случаев без разрыва и, вероятно, даже скомпилировать примерно такой же ассемблер код. –

+0

Хит-хак был, по крайней мере, очень прямолинейным, чтобы создать в то время. Для чего-то более сложного, попробуйте преобразовать алгоритм изоморфизма графа Ю. Р. Ульмана в читаемый код без спагетти. http://www.engr.uconn.edu/~vkk06001/GraphIsomorphism/Papers/Ullman_Algorithm.pdf –

+0

У вас не было ** **, чтобы сделать это таким образом. –

2

GOTO не требуется. Любая вычислимая алгоритм может быть выражена с назначением и сочетанием IF ... THEN, BEGIN ... END, и вашим выбором WHILE ... DO ... END или REPEAT ... UNTIL. Вам даже не нужны подпрограммы. :)

Это известно как теорема о структурированной программе.

Для доказательства см. Статью 1966 года, Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules (PDF) от Corrado Böhm и Giuseppe Jacopini.

Смежные вопросы