Re[4]: Выйти из двух циклов сразу
От: Patalog Россия  
Дата: 05.06.02 04:52
Оценка:
Здравствуйте m.a.g., Вы писали:

...>Здравствуйте Patalog, Вы писали:


P>>Никак не могу понять почему народ так боится goto? Для этого есть какие-то причины помимо эстетических? Ежели есть просветите плиз. А то я иногда пользуюсь, особенно в подобных случаях, и мне кажется это более красиво, чем с переменной...


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


Мсье теоретик? Объясните популярно, что есть "рушится весь конструктивизм и многие теоремы существования"?
И как эту задачу решить с точки зрения "правильного теоретического проектирования".
Почетный кавалер ордена Совка.
Re[10]: Выйти из двух циклов сразу
От: Patalog Россия  
Дата: 05.06.02 04:59
Оценка:
Здравствуйте The Lex, Вы писали:

TL>Здравствуйте Patalog, Вы писали:


[skip]
TL>Вот так вот и представляешь себе обновление софта. И добавление фенечек и рюшечек. И управление всей сетью. И еще много чего. И приборчик работает на пределе. И новые фенечки из него высасывать надо, потому что с рынка улетишь в два счета — конкуренты не дремлют. А приходит новая "железячка": старый софт выбрасывать, да? Вот IT (если я ничего не перепутал) работал в этой сфере — он может подтвердить.

TL>Так что и этот пример, увы, надуман...


Это что, как в нотах некоего Ференса Листа? На одной странице — играть быстро, на 2-й еще быстрее, 3-й быстро как только возможно, и все же на 4-й — еще быстрее. И ежели железо работает на пределе это значит оно работает на пределе. И новых фенечек из него _не_ вытащить. А чтобы не улететь с рынка, нужно делать более другое железо, под которое нужен более другой софт. Т.е. принципы управления и алгоритмы работы железки изменились _полностью_.

А я сейчас работаю в подобной сфере, и что?
Почетный кавалер ордена Совка.
Re[11]: Выйти из двух циклов сразу
От: The Lex Украина  
Дата: 05.06.02 05:09
Оценка:
Здравствуйте Patalog, Вы писали:

P>Здравствуйте The Lex, Вы писали:


TL>>Здравствуйте Patalog, Вы писали:


P>[skip]

TL>>Вот так вот и представляешь себе обновление софта. И добавление фенечек и рюшечек. И управление всей сетью. И еще много чего. И приборчик работает на пределе. И новые фенечки из него высасывать надо, потому что с рынка улетишь в два счета — конкуренты не дремлют. А приходит новая "железячка": старый софт выбрасывать, да? Вот IT (если я ничего не перепутал) работал в этой сфере — он может подтвердить.

TL>>Так что и этот пример, увы, надуман...


P>Это что, как в нотах некоего Ференса Листа? На одной странице — играть быстро, на 2-й еще быстрее, 3-й быстро как только возможно, и все же на 4-й — еще быстрее. И ежели железо работает на пределе это значит оно работает на пределе. И новых фенечек из него _не_ вытащить. А чтобы не улететь с рынка, нужно делать более другое железо, под которое нужен более другой софт. Т.е. принципы управления и алгоритмы работы железки изменились _полностью_.


А те кто делают новое железо, разумеется, выбрасывают на ветер свои инвестиции, каждый раз разрабатывая новые, _полностью_ измененные принципы управления и алгоритмы работы железки?

P>А я сейчас работаю в подобной сфере, и что?


В какой именно, если это, конечно же, не слишком большой секрет?
Голь на выдумку хитра, однако...
Re[10]: Выйти из двух циклов сразу
От: Patalog Россия  
Дата: 05.06.02 05:11
Оценка:
Здравствуйте VladD2, Вы писали:

VD>Здравствуйте Patalog, Вы писали:


P>>Ну, представь себе такую ситуацию.

P>>Есть некий прибор, управляется ета хрень какой-нибудь двушкой в железном ящичке под голым досом. Энтих приборчиков энное количество по всему миру (например в Нижнезадрюпенской области, городе Мухосраннске).
P>>Maintenance с точки зрения новых красивых фенечек ненужен\невозможен по двум причинам — как ты представляешь обновление софта в этой ситуации? И, второе, железо (приборчик) рабоает на пределе, и новых фенечек из него не высосешь. Да и не нужны они, себестоимость тоже нужно учитывать.

VD>Ну, а как ошибочка в тоем замечательном монолите? А ты ркутой goto-шник на goto-зил и свалил в другую контору. Что делать тем беднягам которым приказано исправить ошибку и выложить в Inet патч?


Какой такой Inet в городе Мухосранске? Мсье не допонял исходную посылку. И какая такая ошибка, если монолдит замечательный?
Ежели в моем "замечательном монолите" будет критическая ошибка меня и так уволят И не только меня. А если на этапе эксплуатации обнаружится не критическая ошибка, то баги перековываются в фичи

ЗЫж Что будут делать те "бедняги" меня нисколько не волнует, ибо в человеколюбии замечен не был. Да и самому не раз приходилось оказываться в такой ситуации. Хотя все зависит от ситуации.
ЗЗЫж Вот я и говорю, после ваших ответов у меня складывается впечатление, что все ето замечательное "граммотное структурное программирование" нужно людям дабы править баги после релиза. А не проще то время, которое нужно чтобы каждый чих обернуть в "объектную обертку" (sorry за тафтологию), пытаться вместо одного goto городить кучу if'ов\флагов\и т.д. потратить на то чтбы просто нормально написать\отладить.
Почетный кавалер ордена Совка.
Re[8]: Выйти из двух циклов сразу
От: Patalog Россия  
Дата: 05.06.02 05:57
Оценка:
Здравствуйте IT, Вы писали:

[skip]

IT>Ну давай устроим голосование про что такое программирование и все дружно проголосуем за то, что это искусство. Правда само оно от этого не перестанет быть производством. Высокотехнологичным, наукоёмким, но производством, я бы даже сказал — местами ремеслом.


Я — за :super:

[skip]

IT>Не приходило. Более того, пока ты пишешь программу ты её сам и изменяшь. Или ты никогда не возвращаешься к уже написанному коду? Типа открыл тетрадку начал писать, закончилась тетрадка пошёл сдал результат заказчику? Ну-ну.


Возвращаюсь. И повторю еще раз, тот кусок кода, который прислал Vlad для меня более непонятен, не говоря о более других недостатках :)

[skip]

IT>Не важно подо что пишется софт, под железо или под юзера. Завтра ты получаешь новую версию железа и что, будешь писать под неё софт с нуля или доработаешь предыдущую версию программы? Если она монолитная и неизменяемая и не позволяет добавить пару новых фич, то наверное первое. Дорогой ты получается разработчик для своего работодателя. Тебе бы за эту переделку заплатить как за доработку, а не новую разработку, сразу бы всё стало понятно.


Важно. А "новая версия желаза" она бывает разная, одно дело другой контроллер той же серии (поболее памяти, регистров, побыстрее), а другое дело совершенно _другой_ контроллер. С другой логикой, системой комманд и т.д. Хотя я непосредственно контроллеры не программирую, но интерфейс к железке в целом может кардинально измениться. А насчет "дорогойразработчик" — не к этому ли стремимся? ;) И платят мне именно за доработку.

P>>А maintenance, как ты выразился, в большинстве софтверных контор вырождается в убирание багов уже после релиза.


IT>Правильно. Полтора года назад сидел я одном доткоме и правил баги. Первое с чего всё начиналось — это с преведения исходного кода в божеский вид, расстановки отступов, добавления пробельных строк между процедурами и т.д. На это уходило больше времени чем на исправление самих багов. Этот дотком платил за меня моему работодателю 80 баксов в час, $640/день, $3200/неделю, $14000/месяц. Половиной этих денег оплачивалось форматирование исходных кодов. После того как пара таких самородков, за которыми всё время приходилось убирать ушли, было принято Code Convention и дело пошло на лад. Правда самому доткому уже не долго оставалось жить.


Я рад за тебя. У меня например, много работы уходит именно на то, чтобы разобраться в метрах Open Sorce и переделать это под свои нужды. Мне столько не платят :( А бывает и вообще, неделями из hex-editor'а не вылазишь.

IT>>>Это всё важно, но вторично.


P>>Еще раз повторюсь, есть вещи в которых _ЭТО_ первично. А вот модное слово maintenance вторично, либо совсем не нужно.


IT>Ты говоришь как типичный одиночка, никогда не работавший в команде, тем более в большой. Мне вот и сейчас приходится проводить работу с молодыми и втолковывать им, мол ребята, расслабьтесь, если ты работаешь в команде и на дядю, то твой код тебе не принадлежит. Он пренадлежит команде и дяде. Открывай свою контору и хоть оппишись goto, можешь нанять программистов и заставить их тоже так писать, флаг в руки. А ещё потребуй от них чтобы они тебе наколбасили кода, который бы невозможно было понять другому человеку и повторно использовать. А если они не дай бог вздумают своевольничать и писать универсальные классы и процедуры, да ещё и без goto, то всех лешить премии и уволить.


Может быть. Скорее даже так и есть. Ибо у нас в конторе (cool site) 3 программера, остальные железячники. И пректы наши хоть и пересекаются, но в весьма узких местах. Насчет невозможно понять я уже писал выше, это же отмечал и Alexander Shargin и не только он. В том смысле что гора if'ов\циклов\флагов нисколько не читабельнее, и еще непонятнее. А универсальные классы и процедуры и я пишу, не надо доводить дело до абсурда, о чем я (да и не только я) тоже неоднократно говорил. И Буча я читал, и Брукса и иже с ними. И розу юзал. Если ты еще не понял мою мысль повторю: Использовать goto _иногда_ не только можно, но и нужно.

IT>ЗЫ. Знаешь почему на RSDN'е так медленно появляются новые фичи? В том числе и потому, что если мне нужно что-то добавить в исходнике, с которым мне не приходилось ещё работать, то для начала я должен его переписать по новой. При этом я уважаю Диму, который всё это делал, как талантливого программиста, но была бы моя воля я бы отшлёпал это юное дарование за то, что он видимо как и ты считает maintenance просто модным словом и оно для него "вторично, либо совсем не нужно".


Еще раз. Не надо сравнивать, я извиняюсь, хрен с пальцем. Одно дело RSDN с его новыми фичами, а другое дело "РЧА Аблатор проводящих путей сердца". И даже если мне _сильно_ захочется добавить новую фенечку, мне это _никто_ не даст, ибо придется все сертифицировать заново (не буду сейчас рассказывать, что значить получать ГОСТ на мед. технику), переделывать гору документации, а возможно даже и методики применения\воздействия на которых не один врач защитил докторскую диссертацию. Когда количество нужных "фенечек" приближеатся к некоему пределу, выпускается новый, более другой прибор. С более другим софтом. И старый по большей части используется для метода Copy\Paste.

ЗЫж Помниться я в одном из ответов Vlad'у срошивал All — какие у кого корпоративные правила кодирования. Ибо мне это действительно интересно, и я прекрасно знаю, что с о своим уставом, в чужой монастырь вредно для здоровья. Может все таки поговорим об этом?

ЗЗЫж У нас был один менеджер, который пытался уволить одного как ты выразился одиночку (не меня), дело закончилось тем что выгнали менеджера. И, имхо, это правильно.
Почетный кавалер ордена Совка.
Re[12]: Выйти из двух циклов сразу
От: Patalog Россия  
Дата: 05.06.02 06:03
Оценка:
Здравствуйте The Lex, Вы писали:

TL>Здравствуйте Patalog, Вы писали:


P>>Здравствуйте The Lex, Вы писали:


TL>>>Здравствуйте Patalog, Вы писали:


P>>[skip]

TL>>>Вот так вот и представляешь себе обновление софта. И добавление фенечек и рюшечек. И управление всей сетью. И еще много чего. И приборчик работает на пределе. И новые фенечки из него высасывать надо, потому что с рынка улетишь в два счета — конкуренты не дремлют. А приходит новая "железячка": старый софт выбрасывать, да? Вот IT (если я ничего не перепутал) работал в этой сфере — он может подтвердить.

TL>>>Так что и этот пример, увы, надуман...


P>>Это что, как в нотах некоего Ференса Листа? На одной странице — играть быстро, на 2-й еще быстрее, 3-й быстро как только возможно, и все же на 4-й — еще быстрее. И ежели железо работает на пределе это значит оно работает на пределе. И новых фенечек из него _не_ вытащить. А чтобы не улететь с рынка, нужно делать более другое железо, под которое нужен более другой софт. Т.е. принципы управления и алгоритмы работы железки изменились _полностью_.


TL>А те кто делают новое железо, разумеется, выбрасывают на ветер свои инвестиции, каждый раз разрабатывая новые, _полностью_ измененные принципы управления и алгоритмы работы железки?


Я новое железо не делаю, поэтому принимаю как данное. Ибо не железячник. Вопрос не ко мне. Видимо всетаки есть причини, имхо.

P>>А я сейчас работаю в подобной сфере, и что?


TL>В какой именно, если это, конечно же, не слишком большой секрет?


Не секрет. cool site
Почетный кавалер ордена Совка.
Re[13]: Выйти из двух циклов сразу
От: Sergey Россия  
Дата: 05.06.02 06:36
Оценка:
Здравствуйте VladD2, Вы писали:

AS>>>Во-первых, мне не совсем понятно, почему для противники goto постоянно щеголяют приёмами из арсенала C++. Если goto противоречит принципам структурного программирования, давайте оперировать средствами языка C. То есть никаких исключений, объектных обёрток и пр.


S>>Не, это не честно. Неиспользование goto в C — это уже совсем другой вопрос. Я думаю, экстремистов, утверждающих, что goto не нужен в С куда меньше, чем протестующих против его использования в C++.


VD>Дык, одной из задач при разработке C++ было избавление от вынужденного использования неструктурированноых goto. Кстати, в тот же С структурную обработку иключений ввели и даже лучше чем в С++. А мы всю жизнь COM-объекты на ATL делали без нее и ничего. Ни одного goto в коде и все работает.


Да при чем тут COM-объекты. Оно (goto) реально в основном во всяких вычислительных алгоритмах нужно. Для выхода из вложенных циклов, не более того.

AS>>>Кстати, в Java goto убрали, но расширили синтаксис break для выхода из вложенных циклов. Похоже, ребята рассуждали похожим образом.


S>>И правильно сделали. А комитет по стандартизации C++ правильно делает, что goto не убирает. Хотя break усовершенствовать не помешало бы —


VD>Согласен.


S>>глядишь, goto только в legacy коде и остался бы.


VD>А вот тут нет. Посмотри на голосование. 100%-ых противников goto 5 человек (тебя я там не вдел ;), а сторонников довольно моного).


А я за goto, потому что пока break в С++ недостаточно функциональный. Вот сделают break такой же, как в жабе — проголосую против goto :)

VD>Еще больше удручает C++-ый код того же MS. Там порою встречается идеальный и красивый код, а иногда вот такие прерлы:


VD>
   код поскипан.
VD>


Ну про такой код что говорить — типичный пример сишного стиля в С++ коде. Либо писал человек, которого Страус так и не убедил, что С++ — савсэм другой язык, нежели С, либо это легаси и переписывать некогда/незачем было.

S>>Вот именно! Функция должна выполнять логически завершенное действие, а не служить заменой циклу. Уж лучше goto.


VD>Лучше код разумно писать, тогда и нагромождения циклов не будет. Да и никто не мешает на обычных ифах жить. Все равно оптимизатор все переделает так, что мама родная не узнает.


А у нас в конторе оптимизатор запрещен, как у некоторых goto :). А без нагромождения циклов иногда не обойдешся.

VD>Кстати если посчитать количесвто goto в ATL, то окажется, что там их совесем не много и используется они приимущественно в целях обработки ошибок (VC6 реализовывал try/catch на CRT, от которого ATL-щики избавлялись). Ну, а в WTL вообще нельзя найти ни одного goto (хотя и там ламеры были). У на 5 мегов кода и ни одного goto и ничего живем и все работает.


Ну, в ATL я бы в худшем случае 2 goto оставил, не пользуясь исключениями. Для той обработки ошибок, что там нужна, вполне достаточно объектных оберток и return. А если б мне еще и CRegParser пришлсь переписать, то вероятно, что и вовсе не одного.

AS>>>В-третьих, любители жить без CRT тоже не очень-то жалуют исключения (и ATL/WTL вполне поддерживают такой стиль жизни).


VD>Ну, вот мы как раз такие любители, ну, и что? Ни одного goto нет и CRL не ципляем. И вообще ресурсы в ручную не выделяем все на обертках.


S>>А без CRT — это уже не С++, а "С с классами", да и то урезанный.


VD>Ну, тут ты не прав. Для C++ под Виндовс CRT ненужна. Мы вон сделали 10 оберток над API-шными функциями и все прекрасно работает. Даже STL-ю по большому счету CRT не нужен (хотя мне STL не нравится).


А исключения (для того же STL нужны, кстати)? А конструкция/деструкция глобальных объектов (я слышал, в семерке для это рантайм не нужен, но у меня )? Строки/локали STLные тоже за собой рантайм тянут. А плавающая точка? К четырем прибавть два, конечно, и без CRT можно, но вот чтоб юзеру результат показать — уже хотя бы printf нужен.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[7]: Выйти из двух циклов сразу
От: flyker Россия  
Дата: 05.06.02 07:53
Оценка:
Здравствуйте Patalog, Вы писали:

P>Здравствуйте flyker, Вы писали:


P>[skip]


F>>
F>>for(SDirectoryRecord* pRecord3 = pRecord1->m_pFirstRecord; pRecord3 != NULL; pRecord3 = pRecord3->m_pNextDirectory) {
F>>   if(pRecord3 != pRecord2 && pRecord2->m_nLevel == pRecord3->m_nLevel) {
F>>       nRes = CompareRecord(pRecord2, pRecord3, nType) == 0 ? CCB_ERR_EQUAL_ID : CCB_ERR_NOERROR;
F>>       if(nRes != CCB_ERR_NOERROR) {
F>>            pCheckControl->m_data1 = reinterpret_cast<long>(pRecord2);
F>>            pCheckControl->m_data2 = reinterpret_cast<long>(pRecord3);
F>>            nCallBackRes = pCheckControl->DoControl(nRes); //Передается юзеру, который должен как-то отреагировать на ошибку
F>>            nErrorCount++;
F>>            
F>>            if(nCallBackRes == CCB_RES_MAKEAUTO || nCallBackRes == CCB_RES_IGNORE) continue; //OK, продолжаем дальше
F>>            else if(nCallBackRes == CCB_RES_ABORT) return nErrorCount; //Failed, отмена
F>>            else
F>>            {
F>>                pRecord3 = pRecord1->m_pFirstRecord; //Юзер попытался исправить ошибку, надо проверить заново
F>>                continue;
F>>             }
F>>       }
F>>   }
F>>}
F>>


F>>Я бы так написал, а как другие пишут мне глубоко по барабану, лишь бы не мне читать и править.

F>>Но в данном конкретном случае оба варианта имеют право на жизнь.
F>>Хотя если бы не комментарий в ключевой строке, дольше бы понимал суть.

P>Похоже суть ты так и не понял. Ежели было все так просто, ни о каком goto в данном случае речи бы не было.

P>А комментарий в ключевой строке гласит "Юзер попытался исправить ошибку, надо проверить заново". Дальше продолжать?

Ну ну, ты еще скажи что код не эквивалентен оригиналу.
Все гениальное — просто
Re: Выйти из двух циклов сразу
От: Whisperer  
Дата: 05.06.02 07:54
Оценка:
Здравствуйте LeonGorbachev, Вы писали:



LG>
LG>while(1)
LG>{
LG>  for(int i = 0; i < 100; i++)
LG>  {
LG>    if(i == 77)
LG>      // вот тут хочу выйти вообще из всех циклов - из  for и из while
LG>  }
LG>}
LG>


LG>Как это сделать?


Ау знатоки программирования может вы другие темы смотреть будете и помогать желающим, а
вы обсасываете старую избитую тему (вчем прикол — поговорить, для этого chat существует).
Я смотру если появляется хороший вопрос — ответов или 0 или <10 . Зато на такие темы вы кидаетсесь
как голодные ... (извеняюсь вырвалось). И необежайтесь если я неправ. Мне здесь тоже помогали.
Но активность — только из-за таких тем.
Re[13]: Выйти из двух циклов сразу
От: Alexander Shargin Россия RSDN.ru
Дата: 05.06.02 08:01
Оценка:
Здравствуйте VladD2, Вы писали:


VD>Дык, одной из задач при разработке C++ было избавление от вынужденного использования неструктурированноых goto. Кстати, в тот же С структурную обработку иключений ввели и даже лучше чем в С++. А мы всю жизнь COM-объекты на ATL делали без нее и ничего. Ни одного goto в коде и все работает.


Это вообще ровным счётом ни о чём не говорит. Я, например, могу все свои программы без while/do/for переписать. И всё будет работать.


AS>>>Резюме. Я призиваю участников этого флейма не быть такими категоричными. Эту ветку могут читать начинающие. Не надо прессовать им мозги "незыблемыми правилами". Лучше поучите их думать головой.


VD>Так вот используя goto головой люди обычно и не думают. По этому я призываю начинающих думать головой и никогда не использовать goto.


Ну, это уже демагогия. Похоже, вам с IT довелось много общаться с людьми, которые переходили на C++ со всяких там фортранов и алголов. А мне, например, нет. Меняются поколения, меняются идеалы. Сейчас программисты с самого начала учатся использовать goto умеренно (во всех нормальных книгах об этом написано). Поэтому твои обобщения на "людей", которые "обычно не думают" — не более чем пустые слова.
--
Я думал, ты огромный страшный Бажище,
А ты недоучка, крохотный Бажик...
Re[16]: Выйти из двух циклов сразу
От: Alexander Shargin Россия RSDN.ru
Дата: 05.06.02 08:10
Оценка:
Здравствуйте VladD2, Вы писали:

AS>>Однако используется же. В основном как раз для эмуляции исключений и корректного освобождения ресурсов в глобальном масштабе.


VD>Если бы код CLI забит переходами из if-а в else.


В этом месте я говорил о setjmp/longjmp, которые используюся для организации механизма исключений (как это было сделано в ранних версиях MFC, пока C++ не обзавёлся собственными исключениями). При чём тут goto и обёртки?


AS>>Про Linux могу сказать, что там во многих местах goto использован для повышения эффективности. В таких критичных местах, как планировщик, не станешь заморачиваться с лишними переменными/проверками/функциями, когда можно сделать то, что нужно, напрямик и без потерь.


VD>Во блин! Эффективность на goto! Линукс это давно тормозная и разжиревшая ОС ни чем не отличающаяся от NT.


Речь о ядре, а не о Линуксе в целом. На его основе, между прочим, строят системы реального времени. Из Виндоусов на это может претендовать только CE, но и от неё в этом качестве серьёзные фирмы по размышлении зрелом отказались.


VD>А современные оптимизирующие компиляторы к котрым смело можно причислить VC (которым пользуется MS) и gcc (которым пользуются Линуксойды) оптимизируют в ноль весь оверхэд создаваемый ОО-обертками и лишние if уберают. От ваших вложеных циклов зачастую вообще кмня на камне не остается.


Никуда они не денутся. Если вложенный цикл легко убирается, значит он вообще нафиг не нужен в данном алгоритме, и программисту следовало убрать его из программы самому. Если же он действительно нужен, никакой оптимизатор его не уберёт.
--
Я думал, ты огромный страшный Бажище,
А ты недоучка, крохотный Бажик...
Re[8]: Выйти из двух циклов сразу
От: Patalog Россия  
Дата: 05.06.02 08:26
Оценка:
Здравствуйте flyker, Вы писали:

F>Здравствуйте Patalog, Вы писали:


P>>Здравствуйте flyker, Вы писали:


P>>[skip]


F>>>
F>>>for(SDirectoryRecord* pRecord3 = pRecord1->m_pFirstRecord; pRecord3 != NULL; pRecord3 = pRecord3->m_pNextDirectory) {
F>>>   if(pRecord3 != pRecord2 && pRecord2->m_nLevel == pRecord3->m_nLevel) {
F>>>       nRes = CompareRecord(pRecord2, pRecord3, nType) == 0 ? CCB_ERR_EQUAL_ID : CCB_ERR_NOERROR;
F>>>       if(nRes != CCB_ERR_NOERROR) {
F>>>            pCheckControl->m_data1 = reinterpret_cast<long>(pRecord2);
F>>>            pCheckControl->m_data2 = reinterpret_cast<long>(pRecord3);
F>>>            nCallBackRes = pCheckControl->DoControl(nRes); //Передается юзеру, который должен как-то отреагировать на ошибку
F>>>            nErrorCount++;
F>>>            
F>>>            if(nCallBackRes == CCB_RES_MAKEAUTO || nCallBackRes == CCB_RES_IGNORE) continue; //OK, продолжаем дальше
F>>>            else if(nCallBackRes == CCB_RES_ABORT) return nErrorCount; //Failed, отмена
F>>>            else
F>>>            {
F>>>                pRecord3 = pRecord1->m_pFirstRecord; //Юзер попытался исправить ошибку, надо проверить заново
F>>>                continue;
F>>>             }
F>>>       }
F>>>   }
F>>>}
F>>>


F>>>Я бы так написал, а как другие пишут мне глубоко по барабану, лишь бы не мне читать и править.

F>>>Но в данном конкретном случае оба варианта имеют право на жизнь.
F>>>Хотя если бы не комментарий в ключевой строке, дольше бы понимал суть.

P>>Похоже суть ты так и не понял. Ежели было все так просто, ни о каком goto в данном случае речи бы не было.

P>>А комментарий в ключевой строке гласит "Юзер попытался исправить ошибку, надо проверить заново". Дальше продолжать?

F>Ну ну, ты еще скажи что код не эквивалентен оригиналу.




А что, таки и эквивалентен? В твоей реализации цикл после continue продолжиться не с начала. Т.е. если в первом же проходе возникла ошибка, то после pRecord3 = pRecord1->m_pFirstRecord; цикл будет продослжен с pRecord3 = pRecord3->m_pNextDirectory, т.е. со следующей записи.
Не говоря уже о том, что менять переменную цикла в самом цикле ето, ну, скажем не совсем хорошо. Имхо, много похуже пресловутого goto.

Хинт, посмотри в отладчике:

for(int i = 0; i < 5; i++) {
    if(i == 1) {
        i = 0;
        continue;
    }
}
Почетный кавалер ордена Совка.
Re[16]: Выйти из двух циклов сразу
От: Alexander Shargin Россия RSDN.ru
Дата: 05.06.02 08:38
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте Alexander Shargin, Вы писали:


AS>>А пока — согласен — давай сосредоточимся на C++. Для начала обратимся к теме, которая стоит в сабже. В первом письме я подробно остановился именно на ней. Итак, каким образом поставленная задача решается на C++ лучше, чем с использованием goto?


IT>Это зависит. Я бы хотел видеть код всей процедуры, а не выжимку, которую предоставил LeonGorbachev.


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

for(int i=0; i<1000; i++)
   for(int j=0; j<1000; j++)
      if(i == 666 && j == 123)
      {
         // выходим
      }



IT>Здесь уже давали советы. Я, в зависимости от ситуации, воспользовался бы следующим:


IT>1. Флаг в первом цикле

IT>2. Проверка счётчика второго цикла на завершённость
IT>3. return
IT>4. inline процедура (очень специфический вариант, но возможный)

Эти советы я уже слышал, но, повторяю, на мой взгляд, эти методы проигрывают подходу с goto:

for(int i=0; i<1000; i++)
   for(int j=0; j<1000; j++)
      if(i == 666 && j == 123)
      {
         goto LEndOfOuterLoop;
      }

LEndOfOuterLoop:



В общем, чтобы не быть голословным, пиши свой вариант и аргументируй, чем он лучше в плане а) эффективности б) понятности и в) поддерживаемости/расширяемости. А я пока подумаю о других примерах. ;)


IT>Всё это несомненно и правильно, но goto только усугубит дело. Возможно, просто получилось так, что ты видел много хорошего, старого, добротного кода с использованием goto и много плохого, "современного" и, который долго не проживёт, так как вообще не имеет право на жизнь, с doc/view. Мне приходилось видеть первый, но с качеством второго. Люди сползали с EC-ок, с PL/1 и Фортрана и начинали писать на процедурных языках. :wow: Поверь мне, doc/view, который ты видел — это детский сад по сравнению с теми уродцами, которые выходили из под пера тех программеров. Так же по старинке они печатали свои километровые процедуры, раскладывали их на полу и бродили по ним в поисках меток, которые имеют тенденцию со временем отдаляться от мест их прямого использования. Никакие уговоры не помогали. И мой шеф, мудрый человек, принял решение предать goto анафеме, запретить под угрозой лешения премии. Подействовало. И ты знаешь что самое прикольное? Размер процедур стал уменьшаться, появились элементы декомпозиции, в распечатках необходимость отпала и всё такое.


Вот здесь мы, похоже, добрались до самых истоков твоей ненависти к goto. Игорь, с этого следовало начинать, это позволило бы обойтись без тонны флейма. Вместо всех этих громких слов о неструктурированности, вреде и норкотиках сказал бы, что в вашей конкретной команде эта мера была вынужденным и, возможно, наиболее эффективным средством повысить качество кода и ускорить разработку. Эта мысль была бы встречена на ура и не вызвала бы никаких нареканий.


IT>>>Естественно, цепочки if'ов тоже не лучший пример читабельности, но они вполне нормально заменяют технику, показанную тобой.


AS>>Я скажу больше: они хуже, так как затрудняют и понимание, и расширяемость. Ты сам заметил, что метод с goto сильно напоминает эмуляцию деструкторов, которые и являются наилучшим решением данной задачи. Если в функцию добавляется ещё один ресурс, при моём подходе достаточно:

AS>>- добавить его в секцию переменных
AS>>- добавить код очистки в конец
AS>>- работать с ресурсом как ни в чём не бывало.

AS>>Логика же вложенных if-ов при таком добавлении может полностью измениться. Вот это-то как раз и плохо.


IT>Мои аргументы.

IT>- я никогда не перепутаю порядок освобождения ресурсов, если он важен,

Я тоже. Не вижу связи. Я не перепутаю, ты не перепутаешь, а кто-нибудь возьмёт и перепутает. :)


IT>- я могу работать с ресурсами локально, в определённой точке программы и не держать их долго без надобности, особенно при наличии длинных циклов,


Мой метод тоже это позволяет. Он ведь работает почти как обёртка: ты можешь ждать деструктора, а можешь вызвать очередной Close/Release/Delete и освободить ресурс в любой момент. Нужно только проверить в конце, не был ли ресурс освобождён (проверка на NULL как раз и служит этой цели).


IT>- я могу использовать их в тех же циклах, открывая и закрывая их при каждой итерации,


См. предыдущй пункт. Мой подход не накладывает на эту тактику никаких ограничений.


IT>- я могу использовать return более гибко, в том числе и для сабжа, что в твоём случае невозможно, т.к. программа обязательно должно доползти до конца... хотя ты можешь, конечно, использовать ещё один goto ;)


В случае с if'ами выход работает так: освобождаем все ресурсы/return. У меня — goto cleanup (всегда одна строчка). Не вижу принципиальной разницы.
--
Я думал, ты огромный страшный Бажище,
А ты недоучка, крохотный Бажик...
Re[9]: Выйти из двух циклов сразу
От: flyker Россия  
Дата: 05.06.02 08:40
Оценка:
Здравствуйте Patalog, Вы писали:

P>Здравствуйте flyker, Вы писали:


F>>Здравствуйте Patalog, Вы писали:


P>>>Здравствуйте flyker, Вы писали:


P>>>[skip]


F>>>>
F>>>>for(SDirectoryRecord* pRecord3 = pRecord1->m_pFirstRecord; pRecord3 != NULL; pRecord3 = pRecord3->m_pNextDirectory) {
F>>>>   if(pRecord3 != pRecord2 && pRecord2->m_nLevel == pRecord3->m_nLevel) {
F>>>>       nRes = CompareRecord(pRecord2, pRecord3, nType) == 0 ? CCB_ERR_EQUAL_ID : CCB_ERR_NOERROR;
F>>>>       if(nRes != CCB_ERR_NOERROR) {
F>>>>            pCheckControl->m_data1 = reinterpret_cast<long>(pRecord2);
F>>>>            pCheckControl->m_data2 = reinterpret_cast<long>(pRecord3);
F>>>>            nCallBackRes = pCheckControl->DoControl(nRes); //Передается юзеру, который должен как-то отреагировать на ошибку
F>>>>            nErrorCount++;
F>>>>            
F>>>>            if(nCallBackRes == CCB_RES_MAKEAUTO || nCallBackRes == CCB_RES_IGNORE) continue; //OK, продолжаем дальше
F>>>>            else if(nCallBackRes == CCB_RES_ABORT) return nErrorCount; //Failed, отмена
F>>>>            else
F>>>>            {
F>>>>                pRecord3 = pRecord1->m_pFirstRecord; //Юзер попытался исправить ошибку, надо проверить заново
F>>>>                continue;
F>>>>             }
F>>>>       }
F>>>>   }
F>>>>}
F>>>>


F>>>>Я бы так написал, а как другие пишут мне глубоко по барабану, лишь бы не мне читать и править.

F>>>>Но в данном конкретном случае оба варианта имеют право на жизнь.
F>>>>Хотя если бы не комментарий в ключевой строке, дольше бы понимал суть.

P>>>Похоже суть ты так и не понял. Ежели было все так просто, ни о каком goto в данном случае речи бы не было.

P>>>А комментарий в ключевой строке гласит "Юзер попытался исправить ошибку, надо проверить заново". Дальше продолжать?

F>>Ну ну, ты еще скажи что код не эквивалентен оригиналу.


P>


P>А что, таки и эквивалентен? В твоей реализации цикл после continue продолжиться не с начала. Т.е. если в первом же проходе возникла ошибка, то после pRecord3 = pRecord1->m_pFirstRecord; цикл будет продослжен с pRecord3 = pRecord3->m_pNextDirectory, т.е. со следующей записи.

P>Не говоря уже о том, что менять переменную цикла в самом цикле ето, ну, скажем не совсем хорошо. Имхо, много похуже пресловутого goto.

P>Хинт, посмотри в отладчике:


P>
P>for(int i = 0; i < 5; i++) {
P>    if(i == 1) {
P>        i = 0;
P>        continue;
P>    }
P>}
P>




Даже смотреть не буду, я просто знаю что код

for(int i = 0; i < 1; i++) continue;


Это будет ВЕЧНЫЙ цикл. i++ никогда не произойдет.
Все гениальное — просто
Re[10]: Выйти из двух циклов сразу
От: flyker Россия  
Дата: 05.06.02 08:43
Оценка:
Здравствуйте flyker, Вы писали:

F>Здравствуйте Patalog, Вы писали:


P>>Здравствуйте flyker, Вы писали:


F>>>Здравствуйте Patalog, Вы писали:


P>>>>Здравствуйте flyker, Вы писали:


P>>>>[skip]


F>>>>>
F>>>>>for(SDirectoryRecord* pRecord3 = pRecord1->m_pFirstRecord; pRecord3 != NULL; pRecord3 = pRecord3->m_pNextDirectory) {
F>>>>>   if(pRecord3 != pRecord2 && pRecord2->m_nLevel == pRecord3->m_nLevel) {
F>>>>>       nRes = CompareRecord(pRecord2, pRecord3, nType) == 0 ? CCB_ERR_EQUAL_ID : CCB_ERR_NOERROR;
F>>>>>       if(nRes != CCB_ERR_NOERROR) {
F>>>>>            pCheckControl->m_data1 = reinterpret_cast<long>(pRecord2);
F>>>>>            pCheckControl->m_data2 = reinterpret_cast<long>(pRecord3);
F>>>>>            nCallBackRes = pCheckControl->DoControl(nRes); //Передается юзеру, который должен как-то отреагировать на ошибку
F>>>>>            nErrorCount++;
F>>>>>            
F>>>>>            if(nCallBackRes == CCB_RES_MAKEAUTO || nCallBackRes == CCB_RES_IGNORE) continue; //OK, продолжаем дальше
F>>>>>            else if(nCallBackRes == CCB_RES_ABORT) return nErrorCount; //Failed, отмена
F>>>>>            else
F>>>>>            {
F>>>>>                pRecord3 = pRecord1->m_pFirstRecord; //Юзер попытался исправить ошибку, надо проверить заново
F>>>>>                continue;
F>>>>>             }
F>>>>>       }
F>>>>>   }
F>>>>>}
F>>>>>


F>>>>>Я бы так написал, а как другие пишут мне глубоко по барабану, лишь бы не мне читать и править.

F>>>>>Но в данном конкретном случае оба варианта имеют право на жизнь.
F>>>>>Хотя если бы не комментарий в ключевой строке, дольше бы понимал суть.

P>>>>Похоже суть ты так и не понял. Ежели было все так просто, ни о каком goto в данном случае речи бы не было.

P>>>>А комментарий в ключевой строке гласит "Юзер попытался исправить ошибку, надо проверить заново". Дальше продолжать?

F>>>Ну ну, ты еще скажи что код не эквивалентен оригиналу.


P>>


P>>А что, таки и эквивалентен? В твоей реализации цикл после continue продолжиться не с начала. Т.е. если в первом же проходе возникла ошибка, то после pRecord3 = pRecord1->m_pFirstRecord; цикл будет продослжен с pRecord3 = pRecord3->m_pNextDirectory, т.е. со следующей записи.

P>>Не говоря уже о том, что менять переменную цикла в самом цикле ето, ну, скажем не совсем хорошо. Имхо, много похуже пресловутого goto.

P>>Хинт, посмотри в отладчике:


P>>
P>>for(int i = 0; i < 5; i++) {
P>>    if(i == 1) {
P>>        i = 0;
P>>        continue;
P>>    }
P>>}
P>>


F>


F>Даже смотреть не буду, я просто знаю что код


F>
F>for(int i = 0; i < 1; i++) continue;
F>


F>Это будет ВЕЧНЫЙ цикл. i++ никогда не произойдет.


Млин сори, я ошибся
Все гениальное — просто
Re[17]: Выйти из двух циклов сразу
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.06.02 08:46
Оценка:
Здравствуйте Alexander Shargin, Вы писали:

AS>Никуда они не денутся. Если вложенный цикл легко убирается, значит он вообще нафиг не нужен в данном алгоритме, и программисту следовало убрать его из программы самому. Если же он действительно нужен, никакой оптимизатор его не уберёт.


Ты забываешь про вызовы inline-функции, пустых(на данных момент) функции и т.д.

struct Class
{
  Create(){}
  Destroy(){}
  int Value (){return 1;}
};

Class class[10];
//вот такой цикл компилятор может запросто выкинуть, но я бы "обиделся" на программиста,
// если бы он убил бы этот цикл сам.
for (int i = 0;i < 10; ++i)
{
  class[i].Create();
}


//то же самое и здесь, хороший оптимизатор развернет это в int sum = 10;
int sum = 0;
for (int i = 0; i < 10; ++i)
{
  sum += class[i].Value;
}
Re[11]: Выйти из двух циклов сразу
От: m.a.g. Мальта http://dottedmag.net/
Дата: 05.06.02 08:57
Оценка:
Здравствуйте Patalog, Вы писали:

P>ЗЗЫж Вот я и говорю, после ваших ответов у меня складывается впечатление, что все ето замечательное "граммотное структурное программирование" нужно людям дабы править баги после релиза. А не проще то время, которое нужно чтобы каждый чих обернуть в "объектную обертку" (sorry за тафтологию), пытаться вместо одного goto городить кучу if'ов\флагов\и т.д. потратить на то чтбы просто нормально написать\отладить.


А если произнести магические слова "изменение требований заказчиком"? Структурный (тем более ОО) код подстраивается под новые требования значительно быстрее монолитного.
Re[9]: Выйти из двух циклов сразу
От: flyker Россия  
Дата: 05.06.02 09:02
Оценка:
Я тут подумал...
Да согласен в данном случае goto лучшее решение, без него получается изврат.
Все гениальное — просто
Re[17]: Выйти из двух циклов сразу
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.06.02 09:30
Оценка: 18 (1)
Здравствуйте Alexander Shargin, Вы писали:

AS>Думаю, для начала выжимки будет достаточно. Считай, что у тебя есть вычислительный алгоритм, в котором попался двойной цикл типа


AS>
AS>for(int i=0; i<1000; i++)
AS>   for(int j=0; j<1000; j++)
AS>      if(i == 666 && j == 123)
AS>      {
AS>         // выходим
AS>      }
AS>


В таких задачах часто можно сделать двухмерный "итератор" (в паре задач я так делал, когда надо было часто бегать по двухмерной областе).

for (Pos i(0, 0); i < Pos(1000, 1000); ++i)
{
  if (i.x == 666 && i.y == 123)
    break;
}



IT>>1. Флаг в первом цикле

IT>>2. Проверка счётчика второго цикла на завершённость
IT>>3. return
IT>>4. inline процедура (очень специфический вариант, но возможный)

Я бы еще добавил:
5. использовать goto, но спрятать за макросами (одиннаковыми для всей команды)
6. вышеприведенный двухмерный "итератор"
Re[18]: Выйти из двух циклов сразу
От: Alexander Shargin Россия RSDN.ru
Дата: 05.06.02 09:32
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>Здравствуйте Alexander Shargin, Вы писали:


AS>>Никуда они не денутся. Если вложенный цикл легко убирается, значит он вообще нафиг не нужен в данном алгоритме, и программисту следовало убрать его из программы самому. Если же он действительно нужен, никакой оптимизатор его не уберёт.


DG>Ты забываешь про вызовы inline-функции, пустых(на данных момент) функции и т.д.

[skip]

Да, согласен, про уборку цикла программистом я погорячился. Но согласись, что это не меняет сути. Вложенные циклы с большим количеством итераций используются в таких областях, как математические расчёты, обработка текста и т. п. Там они делают содержательную, полезную работу, которую никуда не уберёшь. Чудес не бывает.
--
Я думал, ты огромный страшный Бажище,
А ты недоучка, крохотный Бажик...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.