0iStalker
>Вот эти вот брейки с флагом отмены превращают код в адище
Получается лабиринт
Mirrel
>а если при множественных циклах, при разных условиях, должен быть определённый результат? И при чём в разных ситуациях разный.
>В таких ситуациях goto нивелирует лишний код, когда в этой же ситуации, пытаться ещё условия прописать, даст больше лапшекода, лишних функций, которые практически ни чего не делают или что-нибудь подобное
Ну, так ООП-ное программирование зачастую на 2/3 состоит из многократно дублирующего кода. При этом стремятся всё разложить по полочкам и упорядочить. Да, наверное, можно писать более лаконично, если GOTO в этом помогает, то замечательно
0iStalker
>Вынос ветки кода в отдельную процедуру/функцию и/или тернарные операторы избавляют от необходимости goto почти в 100% кода
Была мысль, что GOTO плохо совместим с новым синтаксическим сахаром в программировании. Не знаю, насколько это верно.
Dmitry_Milk
> очистка ресурсов в сишной программе
А если в С++? Там по-нормальному все деструкторами чистится, хоть при return, хоть при break/continue, хоть при throw.
Dexus
> Есть много разных способов как имитировать goto, без goto, но выглядят они уродливее goto
Так есть примеры неуродливого goto, которые нельзя заменить неуродливыми labeled break/continue?
0iStalker
> Вынос ветки кода в отдельную процедуру/функцию и/или тернарные операторы избавляют от необходимости goto почти в 100% кода, занимающегося вычислениями, в котором нет циклов ожидания.
я веду речь о частных случаях, а не о 99% решений.
Хватит уже меня за новичка считать. Хочешь уточнить что-то задавай вопросы, а не делай поспешные выводы. При том, что сам же с примером "прокололся".
true_bump
> если GOTO в этом помогает, то замечательно
большинство не знают, когда "правильно" его использовать. Именно по этой причине и стараются, чтоб не
0iStalker
> в отдельном потоке работает, чтобы GUI не зависал
не-не. грех какой - потоки прибивать!
процесс прибить!
> это значит что в него и аппаратуру нужно вернуть (отключить высоковольтные блоки питания, отключить ТЭН, вентиляторы, итд)
как насчёт дополнительного процесса, который возвращает аппаратуру в состояние 0?
буквально сейчас проблема на работе.
установка пво (рлс+пусковая установка), в пассивном режиме агритсч неизвестно на что, и почти выпускает ракету.
После чего переключается в режим подтверждения поражения цели. И остаётся в нём, даже когдв оператор переходит в активный режим
и проблема имеенно в железке и её прошивке. Потому что контрольеый пуль (гуй) в этот момент установку не напрягает ничем.
но перезапуск гуя (который разрывает и восстанавлиает соединение с рлс) решает проблему!
получается, что в гуе надо делать костыль. Если обнаружен такой вот фиктивный пуск, и переподсоединятся к установке
Dmitry_Milk
> А если в С++?
Было уже объяснено в https://gamedev.ru/flame/forum/?id=153724&page=15&m=6089967#m214 во втором абзаце.
Вопрос реально не в том "возможно/не возможно", а в том насколько чище, понятнее и проще для изменения код становится.
Девил, кстати, очень кстати вспомнил такой инструмент как finally - он тоже помог бы в плюсах делать код без goto в массе мест даже на сырых не завёрнутых в классы ресурсах, но его официально не ввели еще в стандарт насколько я знаю. А давно пора бы ибо самодельные утилитарные классы реально работают, но еще и в макрос надо заворачивать.
skalogryz
> как насчёт дополнительного процесса, который возвращает аппаратуру в состояние 0?
А открытые хэндлеры ком-портов и tcp сокетов, как пропихнуть в этот дополнительный процесс? То что ресурсы освободились, не значит, что все нужные команды отосланы. А нештатное освобождение хэндлера не значит, что он потом штатно откроется (винда такая винда)
0iStalker
при запуске процесса можно указать наследование хендлов (и вин и никсы умеют)
https://learn.microsoft.com/en-us/windows/win32/sysinfo/handle-inheritance
=A=L=X=
> Было уже объяснено
=A=L=X=
> низкоуровневых объектов с хендлами в WinAPI жопой жуй и когда нужно просто сварганить код который какие нибудь сокеты шурудит или типа того - ну проще так - в конце функции метка fail: в которой закрываются все открытые выше хендлы если они не INVALID_HANDLE
Не, я такой код сейчас опасаюсь писать. Внимание ни к черту стало, и если сэкономить время на обертках - потом гораздо больше времени уйдет на отлов вещей, пропущенных по невнимательности.
Приведу пример из личного кода для goto fail:
// 0 - success, <0 - errors int simple_server::init(int port, int bcastp, const char *bcast_saddr, const char *bcast_msg ) { WSAData wData; SOCKADDR_IN addr; int res = 0; // ok char broadcast = '1'; this->bcast_msg = bcast_msg; //writeToLog( "BCASTMSGIS:" + this->bcast_msg ); error_msg.clear( ); data.clear( ); if ( WSAStartup( MAKEWORD( 2, 2), &wData ) != 0 ) { error_msg = L"WSA Startup failure (" + getWSAErrorString( ) + L")"; res = -1; goto fail; } wsa_started = true; // Setup server socket addr.sin_addr.S_un.S_addr = INADDR_ANY; addr.sin_port = htons( port ); addr.sin_family = AF_INET; server_s = socket( AF_INET, SOCK_STREAM, 0 ); if ( server_s == INVALID_SOCKET ) { error_msg = L"Socket creation failure (" + getWSAErrorString( ) + L")"; res = -2; goto fail; } set_socket_blocking( server_s, false ); if ( bind( server_s, ( struct sockaddr*)&addr, sizeof( addr) ) == SOCKET_ERROR ) { error_msg = L"Socket bind failure (" + getWSAErrorString( ) + L")"; res = -3; goto fail; } if ( listen( server_s, SOMAXCONN ) == SOCKET_ERROR ) { error_msg = std::wstring( L"Listening at port " ) + longToStr( ntohs( addr.sin_port ) ) + L" failed (" + getWSAErrorString( ) + L")"; res = -4; goto fail; } // Setup broadcast socket bcast_s = socket( AF_INET, SOCK_DGRAM, 0 ); if ( bcast_s == INVALID_SOCKET ) { error_msg = L"Broadcast socket creation failure (" + getWSAErrorString( ) + L")"; res = -5; goto fail; } if ( setsockopt( bcast_s, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) < 0 ) { error_msg = L"Broadcast init failure (" + getWSAErrorString( ) + L")"; res = -6; goto fail; } bcast_addr.sin_family = AF_INET; bcast_addr.sin_port = htons( bcastp ); //bcast_addr.sin_addr.s_addr = INADDR_BROADCAST; bcast_addr.sin_addr.s_addr = inet_addr( bcast_saddr ); //"192.168.0.255" ); goto end; // all is ok fail: cleanup( ); end: return res; }
Он немного "испорчен" тем, что это уже метод объекта, где cleanup() всё почистит и можно все goto fail; переделать на cleanup(); return res;
И это верно - в данном конкретном случае это так - но я всегда продолжаю такой шаблон кода сохранять, т.к. может затесаться промежуточный не нужный классу ресурс который таки потребует своего if ( handle != nullhandle ) releaseHandle( handle) и тогда в этом шаблоне я только одну строку добавлю и весь он продолжит работать.
Это конкретный и проверенный временем шаблон. Где goto линеаризирует код, делает код понятнее и проще.
Один раз заворачиваешь хендлы в раиишные классы с деструктором и всё
1 frag / 2 deaths
> Один раз заворачиваешь хендлы в раиишные классы с деструктором и всё
Типа не читал, но осуждаю? По ссылке же было про это написано уже на позапрошлой странице.
Было уже объяснено в https://gamedev.ru/flame/forum/?id=153724&page=15&m=6089967#m214 во втором абзаце.
Для тебя - третий абзац.
skalogryz
> соответственно, сами сеньёры, чтобы сэкономить себе силы, время и палки для битья, в интернетах пропагандируют "неиспользование гото", а всякие попытки обсуждать: "нет, давайте всё-таки гото использовать" присекают.
Ровно до того момента как на очередном ревью не получат извращение типа того switch (n) { case 2: release(drei); [[fallthrough]] case 1: release (einz); } — тогда нормальный трезвый здоровый на голову чел скажет "вот тут гоуту нужен, перепиши на гоуту", джун переписывает на гоуту, в проект заливается код на гоуту.
Ну и плюс ещё сами сеньоры, обычно, тоже код пишут, а не только гребцами погоняют. Они знают и используют инструменты по назначению.
RikiTikiTak
> Ложил я болт на негласные правила.
Запомни, сынок, раз и навсегда. Если ты плюнешь в коллектив, то коллектив утрется. А если наоборот, то ты утонешь ;)
Я ваш гавту не любил.