В чем прелесть замаскированного goto?
От: enji  
Дата: 08.09.10 18:31
Оценка: :)
В последнее время часто встречаю что-то вроде
do
{
  if () break;

  if () break;

} while(false);

switch(0)
{ case 0:

  if () break; 

}


тут недавно пробегала тема с
for(;;)
{
  if () break;
  if () continue;

  break;
}

и там же мелькал if_break

Собственно вопрос — чем такой код лучше goto?

Я в курсе, что goto стоит избегать и согласен с этим, но зачем его маскировать циклами или switch? Все же goto встроен в С/С++, а идиома "цикл, который выполняется 1 раз" — какая-то искусственная...



10.09.10 12:19: Перенесено модератором из 'C/C++' — Кодт
Re: В чем прелесть замаскированного goto?
От: _stun_ Россия  
Дата: 08.09.10 18:46
Оценка:
Борьба с человеческим фактором. Чтобы scope не забыть создать.
Re: В чем прелесть замаскированного goto?
От: uzhas Ниоткуда  
Дата: 08.09.10 18:59
Оценка: :)
Здравствуйте, enji, Вы писали:

E>Собственно вопрос — чем такой код лучше goto?

а ручки-то вот они (с)
Re: В чем прелесть замаскированного goto?
От: Sni4ok  
Дата: 08.09.10 19:08
Оценка: 1 (1)
Здравствуйте, enji, Вы писали:

E>Я в курсе, что goto стоит избегать и согласен с этим, но зачем его маскировать циклами или switch?


возможно боятся негодования социально более высоких, но при этом недалёких программистов(gotoфобов) в конторе которой работают.
Re: В чем прелесть замаскированного goto?
От: andy1618 Россия  
Дата: 08.09.10 19:16
Оценка: +1
Здравствуйте, enji, Вы писали:

E>В последнее время часто встречаю что-то вроде

E>
E>do
E>{
E>  if () break;

E>  if () break;

E>} while(false);

E>



E>Собственно вопрос — чем такой код лучше goto?


Он более структурный и предсказуемый (для goto придётся ещё метки ставить — громоздко и можно ошибиться).
Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.
Re: В чем прелесть замаскированного goto?
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 08.09.10 19:16
Оценка: 5 (4) +2
Здравствуйте, enji, Вы писали:

E>Собственно вопрос — чем такой код лучше goto?


На правах ИМХО.
goto по своей природе слишком "мощный". Если я вижу break, я точно знаю, что переход произойдёт в конец текущего блока-цикла. Если я вижу goto, то знаю, что перейти он может куда угодно, и восприятие кода сразу усложняется. Кроме того, с goto легче допустить какой-нибудь ляпсус, воткнув пару операций между концом блока и меткой, или просто опечатавшись каким-нибудь CYCLE1_END вместо CYCLE2_END, а потом удивляться, чего это поток управления скачет по всей функции взад-вперёд.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[2]: В чем прелесть замаскированного goto?
От: Sni4ok  
Дата: 08.09.10 19:21
Оценка:
Здравствуйте, andy1618, Вы писали:

A>Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.


а из двойного цикла вы как предлагаете выходить, кучу флажков с проверкой вставлять?
Re[2]: Re: В чем прелесть замаскированного goto?
От: enji  
Дата: 08.09.10 19:44
Оценка: +1
Здравствуйте, andy1618, Вы писали:
A>Он более структурный и предсказуемый
Насколько я понимаю, "нехороши" все нарушения потока выполнения — break, continue, много return-ов...
Правда goto — самый нехороший

A>(для goto придётся ещё метки ставить — громоздко и можно ошибиться).

Ну а так приходится писать do {} while(false) — еще более громоздко...

A>Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.

Понятно, что можно переписать код без goto; часто он при этом улучшается (а иногда — ухудшается ), вопрос в другом — зачем "маскировать" goto?
Re[2]: Re: В чем прелесть замаскированного goto?
От: enji  
Дата: 08.09.10 19:50
Оценка: +1
Здравствуйте, CaptainFlint, Вы писали:

CF>На правах ИМХО.

CF>goto по своей природе слишком "мощный". Если я вижу break, я точно знаю, что переход произойдёт в конец текущего блока-цикла. Если я вижу goto, то знаю, что перейти он может куда угодно, и восприятие кода сразу усложняется. Кроме того, с goto легче допустить какой-нибудь ляпсус, воткнув пару операций между концом блока и меткой, или просто опечатавшись каким-нибудь CYCLE1_END вместо CYCLE2_END, а потом удивляться, чего это поток управления скачет по всей функции взад-вперёд.

Это да, но ведь и сам цикл — довольно "сложная" конструкция, затрудняющая понимание программы. Я вижу goto — это именно переход; я вижу цикл — зачем он? Сколько раз мы по нему пройдем, когда выйдем? А если while(false) — далеко внизу и не бросается в глаза...

Я не спорю с тем, что код с большим кол-вом goto сложен для чтения и понимания; скорее всего его стоит переписать. Но маскировать goto циклами — какое-то странное решение, ИМХО
Re[3]: В чем прелесть замаскированного goto?
От: dilmah США  
Дата: 08.09.10 19:52
Оценка:
E>Правда goto — самый нехороший

longjmp самый нехороший.
goto в С/C++ это безобидная локальная инструкция.
Re[3]: В чем прелесть замаскированного goto?
От: fk0 Россия https://fk0.name
Дата: 08.09.10 20:08
Оценка: :)))
Здравствуйте, Sni4ok, Вы писали:

A>>Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.


Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя.

S>а из двойного цикла вы как предлагаете выходить, кучу флажков с проверкой вставлять?


Профессиональные программисты используют longjmp()! goto -- для ламиров!
Re[3]: В чем прелесть замаскированного goto?
От: fk0 Россия https://fk0.name
Дата: 08.09.10 20:13
Оценка:
Здравствуйте, enji, Вы писали:

E>Я не спорю с тем, что код с большим кол-вом goto сложен для чтения и понимания; скорее всего его стоит переписать. Но маскировать goto циклами — какое-то странное решение, ИМХО


Это не более, чем плохонькая замена вложенным и анонимным функциям. В нормальных языках оно искаропки есть.
Re[4]: В чем прелесть замаскированного goto?
От: fk0 Россия https://fk0.name
Дата: 08.09.10 20:14
Оценка: +1
Здравствуйте, dilmah, Вы писали:

E>>Правда goto — самый нехороший

D>longjmp самый нехороший.

Тогда, если быть последовательным, нужно исключать и использование исключений.
Re[4]: В чем прелесть замаскированного goto?
От: dilmah США  
Дата: 08.09.10 20:18
Оценка:
fk0> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя.

но в С++ есть локальные структуры.
Re[3]: В чем прелесть замаскированного goto?
От: qqqqq  
Дата: 08.09.10 20:22
Оценка: :)
Капитан на вопрос ответил полностью. О себя хочу добавить, что ничего нового или необычного в тех конструкциях нет. Я даже не могу понять, как еще можно было написать алгоритм, который читает и обрабатывает какие-то там данные будь то из сокета или из файла, если не известно сколько их там и надо обрабатывать ошибки. Можно, конечно, вместо тех break-ов поставить условия в операторы циклов или поменять условия наоборот вместо continue, но иногда это не делают по разным причинам. По мне, так особенно большой связи с гото не наблюдается, за исключением того, что все нетривиальные нелинеиные программы в конечном счете набор операций и jump-ов из одного места в другое, как и гото.
Re[4]: В чем прелесть замаскированного goto?
От: qqqqq  
Дата: 08.09.10 20:40
Оценка: +1
не заметил, что циклы по одной итерации. Действительно странно, я ни разу не видел такого
Re[4]: В чем прелесть замаскированного goto?
От: enji  
Дата: 08.09.10 20:51
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Это не более, чем плохонькая замена вложенным и анонимным функциям. В нормальных языках оно искаропки есть.


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

Как вам могут помочь анонимные функции, я не понял.
Re[5]: В чем прелесть замаскированного goto?
От: enji  
Дата: 08.09.10 20:52
Оценка:
Здравствуйте, dilmah, Вы писали:

fk0>> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя.


D>но в С++ есть локальные структуры.


локальные структуры в отличие от вложенных функций (в дельфи\gcc) не могут использовать локальные переменные...
Re[6]: В чем прелесть замаскированного goto?
От: Alexey F  
Дата: 08.09.10 20:57
Оценка:
Здравствуйте, enji, Вы писали:

E>локальные структуры в отличие от вложенных функций (в дельфи\gcc) не могут использовать локальные переменные...

Но могут иметь члены-данные, разделённые между всеми вложенными методами. Не самый удобный вариант на многих сценариях, лямбды из C++0x были бы предпочтительнее.
Re[3]: В чем прелесть замаскированного goto?
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 08.09.10 21:04
Оценка:
Здравствуйте, enji, Вы писали:

E>Это да, но ведь и сам цикл — довольно "сложная" конструкция, затрудняющая понимание программы. Я вижу goto — это именно переход; я вижу цикл — зачем он? Сколько раз мы по нему пройдем, когда выйдем? А если while(false) — далеко внизу и не бросается в глаза...


Да, есть такая проблема. Но таковы ограничения языка, что у него нет нормальных способов работы с выделенными блоками кода. Поэтому сама идея использования цикла для однократного прохода поначалу выглядит несколько невнятно и может сбивать с толку. Однако после понимания сути происходящего удобство использования подобной конструкции может превысить неудобства синтаксиса.

Кроме того, если не нравится цикл, можно его замаскировать под блок какими-нибудь дефайнами типа BLOCK_BEGIN (do), BLOCK_END (while(0)), BLOCK_EXIT (break). Это скорее вопрос привычки и личного восприятия.

E>Я не спорю с тем, что код с большим кол-вом goto сложен для чтения и понимания; скорее всего его стоит переписать. Но маскировать goto циклами — какое-то странное решение, ИМХО


Про вермишелевый код с кучей goto я сейчас не говорю, это тема отдельного разбирательства. Тут всё-таки речь идёт не о goto как таковых, а о конкретном сравнении двух подходов: а) обычный блок кода с выходом из него по goto (блок тут не в смысле языковой конструкции, а просто с точки зрения логики кода), б) псевдо-цикл с однократным проходом и выходом по break, исполняющему роль того же goto. Так вот, ключевое слово break позволяет читателю кода сразу же понять, куда пойдёт программа в случае выполнения соответствующего условия. А именно, break однозначно утверждает, что точка перехода находится ниже по коду программы и совпадает с точкой окончания текущего цикла. Конечно, это не исчерпывающая информация — до конца цикла тоже ещё дойти надо. Но если вместо break стоит goto, то у нас даже этой неполной информации нет, т.к. метка может располагаться где угодно. Да, её можно назвать END_OF_CYCLE, да, её можно расположить в конце цикла. Но можно ведь и не располагать, вот в чём проблема. И читатель кода, пока явным образом не полезет и не найдёт точное расположение метки, не может быть уверенным, что программист воткнул эту метку куда надо было, а не куда захотелось его левой пятке.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.