skalogryz
> суровая реальность жизни.
> испоганят проект на раз-два.
Твой номер шестнадцатый, не ты тот проект создавал, не тебе и волну гнать ;)
Имбирная Ведьмочка
> в проект заливается код на гоуту.
да. но на сеньёров управу тоже нашли - раст!
totoro
верно глаголишь!
по-этому я в рабочее время геймдевом занимаюсь
=A=L=X=
> и можно все goto fail; переделать на cleanup(); return res;
Кстати, не то что "можно, но не нужно", а даже "можно, но нельзя". От вида такой замены чувство эстетики прямо-таки орёт: "Дубликация кода!!"
skalogryz
> да. но на сеньёров управу тоже нашли - раст!
И где он, этот ваш раст? Полтора лгбт в фурсьютах чего-то на нём попиливают, а все остальные — так и дальше педалят на крестах или вообще на голом си.
Dmitry_Milk
> Так есть примеры неуродливого goto, которые нельзя заменить неуродливыми labeled break/continue?
А какая разница, если бряк/кантинь на метку в реальном мире пока ещё не существует? Вот ты написал процедуру на сиплюсплюс с типа неуродливым гоуту, а религиозники ведь триггерятся на само слово — безотносительно насколько оно реально там запутывает или наоборот, так что и тебе скажут: «гото=говно, пупукака, бебебе, мазут», и что ты тогда сделаешь в ответ? Отложишь ПР на 15 лет, пока в цпп таки добавят фичу и у вас обновят компиляторы? Перепишешь на стейт-машину курильщика с break_again=true; break; } if (break_again) break; ? Или всё-таки скажешь — это всё конечно в идеалистичной романтичности по-своему метафизически замечательно, но на практике, конкретно в текущем моменте во времени и пространстве, всё что не гоуту сделает код только хуже, так что идите отсюда со своими догмами и собачку за собой тоже заберите?
=A=L=X=
Хендлов в винапи не так много
Имбирная Ведьмочка
> Отложишь ПР на 15 лет, пока в цпп таки добавят фичу и у вас обновят компиляторы? Перепишешь на стейт-машину курильщика с break_again
Обычно в таких случаях я стараюсь такие циклы вынести в отдельную функцию, откуда выход по return или по исключению.
Но если слишком геморно (например, много переменных захвачено) - то да, стейт-машина, но стараюсь, чтоб было менее накуренным, типа такого:
bool found = false;
for ( int i ... ; i < ... && !found; i++ ) {
while( !found && ... ) {
...
if ( ... ) {
found = true;
break;
}
...
}
}Имбирная Ведьмочка
> Ну и плюс ещё сами сеньоры, обычно, тоже код пишут, а не только гребцами погоняют. Они знают и используют инструменты по назначению.
цитата чужих слов (явно сеньора):
тхлид, увидев код с goto в нормальной конторе обычно увольняет такого говнокодера, по причине того, что ему лень думать или проще втыкнуть goto, а такие нахрен ни кому не нужны.
Mirrel
> цитата чужих слов (явно сеньора):
>
> тхлид, увидев код с goto в нормальной конторе обычно увольняет такого говнокодера, по причине того, что ему лень думать или проще втыкнуть goto, а такие нахрен ни кому не нужны.
А в США бомжи живут в палатках на улице, и что? Не будь бомжом, и будешь много зарабатывать и жить зажиточно. Не будь тупым джуном который суёт гоуту везде куда не надо, и всё у тебя будет в порядке.
Имбирная Ведьмочка
> Не будь тупым джуном который суёт гоуту везде куда не надо
кто сказал, что я его везде сую? )))
Mirrel
> кто сказал, что я его везде сую? )))
А что, тот говнокодер, которго техлид уволил за гоуту — это ты?
Имбирная Ведьмочка
> А что, тот говнокодер, которго техлид уволил за гоуту — это ты?
это цитата чужих слов. Где там сказано, что меня уволили?
Dmitry_Milk
> но стараюсь, чтоб было менее накуренным, типа такого:
Это можно, но это как раз "менее читабельно, более мусорно, хуже в сопровождении и апгрейде".
Тут нужно чётко осознать, что правильно применённый goto в этом случае:
а) не несёт никаких проблем
б) доставляет преимущества
в) не обладает недостатками
г) предоставляет ускорение кода
д) улучшает понимание происходящих переходов
е) не несёт рисков и просадок производительности
ж) делает код прозрачнее и проще для понимания
з) избавлен от подводных камней и сайд-эффектов
к) делает только то, что нужно делать по задаче и ничего другого
л) не делает того что не нужно делать по задаче
м) обладает машинноэффективностью
н) не заставляет компилятор делать того, что по сути задачи делать не надо
о) чётко выражает намерение программиста
п) не замутняет код
р) лаконичен
с) опрятен
т) не раздувает код ненужными конструкциями
Мне тут уже действительно начинает казаться, что мы забываем в чём была истинная проблема goto.
А она реально была.
Она была в том, что подавляющее большинство этих пунктов в доисторическом уже программировании из начала 80-х нарушалось.
И красноречивым свидетельством был BASIC 8-битной эпохи с IF ... THEN GOTO 2030 в каждой десятой строке программы - это было ужасно во всём.
Вот тот 8-битный бейсик был самым долгим носителем "ужасов goto" после длительной эпохи до того когда все на больших ЭВМ уже пересели на ЯВУ с нормальными блочными операторами.
И именно там надо искать проблему - именно там она и была. Именно низведение просматривающего код до дизассемблерщика который копается в пачках JNE LABEL не имея перед глазами структуру кода - это вот именно то зло с которым структурирование кода и призвано было бороться.
Неструктурированный goto - зло. Абсолютное.
Но если правильно и где надо - он уже структурированный и только помогает писать быстрые понятные и правильные программы.
Насчёт finally, кстати, это реально в плюсах интересный момент когда можно реально безопасно без goto делать финализации:
template<typename T> class Deleter { const T &x; public: Deleter(const T &functor ): x( functor ) { }; ~Deleter( ) { x( ); }; }; #define ALX_FINALLY_IMPL2( line, code) auto lambda##line { [&]( ) { code; } }; alx::Deleter< decltype( lambda##line ) > deleter##line{ lambda##line }; #define ALX_FINALLY_IMPL( line, code) ALX_FINALLY_IMPL2( line,code) #define ALX_FINALLY( code) ALX_FINALLY_IMPL( __LINE__, code)
пример использования:
... GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER ); ALX_FINALLY( if ( vertexShader ) glDeleteShader( vertexShader ) ); ...
В таком коде больше нет нигде goto - есть только throw при возникновении ошибок и всё будет чиститься как положено.
Девил на прошлых страницах своё видение вопроса предлагал, но он обмазал синтаксис метками.
Мне кажется удобнее и проще было бы всё-таки сделать в виде оператора:
finally ...;
где ... может быть составным оператором, т.е. { ...; ...; .... };
skalogryz
> RikiTikiTak
> > Если в коде не разобрался, то нужно разобраться прежде чем его править.
> а это уже выливается в проблему цены разработки.
> чтобы внести некую "малую функциональную правку", нужно знать все 100% проекта, или малую часть проекта, которая касается правки 0.05%?
Нужно вносить правки так что бы ничего не ломать и больше меня ничего не интересует, хоть на 200% процентов изучи проект или его совсем не изучай это проблемы индейцев.
skalogryz
> Нужна модульность (куски кода друг от друга независят)
> Отсутствие глобальных привязок.
> Отсуствие неочевидностей.
Хорошая мантра, но ты сначала определись что тебе нужно ибо модульность это когда порядок вызова функций не важен, если важен то есть глобальные привязки. Но мне вот кажется что ты даже не понимаешь что такое глобальная привязка — это когда функции зависят друг от друга, а не когда есть глобальные переменные. Я вот думаю что и с базами данных ты никогда не работал.
Что бы не было неочевидность нужно поднимать свою квалификацию.
Mirrel
> это цитата чужих слов. Где там сказано, что меня уволили?
А ты что подумал, что это я лично тебе даю указания как делать? Это было обобщённо-личное предложение, под "ты" в том сообщении следует понимать любого, кто попал в такую ситуацию.